web-dev-qa-db-fra.com

Comment supprimer le préfixe du nom de fichier avec un shell Posix

Comment puis-je supprimer le préfixe du nom de fichier dans Bash comme dans l'exemple suivant:

XY TD-11212239.pdf

obtenir

11212239.pdf

c'est-à-dire, supprimez XY TD-?

26
hamid

Vous avez donné très peu d'informations, mais en supposant que vous le faites dans bash et que vous avez une liste de fichiers dont le préfixe doit être supprimé, vous pouvez diriger la liste via sed:

Par exemple:

./generate_your_list_of_files | sed -e 's/^prefix//'

ou si votre liste de fichiers est séparée par des espaces:

echo TD-file1 TD-file2.x.yt TD-file3-beep | sed -e 's/\<TD-//g'

Le premier correspond au préfixe au début de la ligne et le supprime. Le second correspond à TD- (ou tout autre préfixe que vous souhaitez remplacer) uniquement lorsqu'il se produit au début d'un mot et le remplace dans toutes les correspondances de toutes les lignes. Cela pourrait devenir dangereux, par exemple un fichier comme TD-file\ that\ TD-contains\ space.txt devient file\ that\ contains\ space.txt

En remarque, n'obtenez pas votre liste de fichiers en utilisant ls. C'est une horrible erreur . Si vous avez besoin d'obtenir une liste de fichiers avec lesquels travailler et auxquels vous pouvez vous référer à plusieurs endroits, je vous suggère de les mettre dans un tableau:

files=(*)

puis travailler avec ce tableau.


En raison de demandes courantes (le seul commentaire ci-dessous), voici comment renommer tous les fichiers du répertoire commençant par XY TD- de telle sorte que le préfixe soit supprimé (Merci à @tripleee):

for file in prefix*;
do
    mv "$file" "${file#XY TD-}"
done
29
Shahbaz

Vous avez dit POSIX shells qui incluraient BASH, Kornshell, Ash, Zsh et Dash. Heureusement, tous ces shells font filtrage de motifs sur les valeurs variables.

Les modèles sont ce que vous utilisez lorsque vous spécifiez des fichiers avec des choses comme * sur la ligne de commande Unix/Linux:

$ ls *.sh  # Lists all files with a `.sh` suffix

Ces shells POSIX utilisent quatre filtrages de motifs différents:

  • ${var#pattern} - Supprime la plus petite chaîne du côté gauche qui correspond au modèle.
  • ${var##pattern} - Supprime la plus grande chaîne du côté gauche qui correspond au modèle.
  • ${var%pattern} - Supprime la plus petite chaîne du côté droit qui correspond au modèle.
  • ${var%%pattern} - Supprime la plus grande chaîne du côté droit qui correspond au modèle.

Voici quelques exemples:

foo="foo-bar-foobar"
echo ${foo#*-}   # echoes 'bar-foobar'  (Removes 'foo-' because that matches '*-')
echo ${foo##*-}  # echoes 'foobar' (Removes 'foo-bar-')
echo ${foo%-*}   # echoes 'foo-bar'
echo ${foo%%-*}  # echoes 'foo'

Vous n'avez pas vraiment expliqué ce que vous vouliez et vous n'avez inclus aucun exemple de code, il est donc difficile de trouver quelque chose qui fera ce que vous voulez. Cependant, en utilisant le filtrage de motifs, vous pouvez probablement déterminer exactement ce que vous voulez faire avec vos noms de fichiers.

file_name="XY TD-11212239.pdf"
mv "$file_name" "${file_name#*-}" # Removes everything from up to the first dash
27
David W.

Vous pouvez également utiliser l'outil renommer

Installez-le avec homebrew

brew install rename

Exécutez ensuite la commande ci-dessous depuis le répertoire pour supprimer le "préfixe" de tous les fichiers

rename -d prefix- *

5
Ken Prince

En plus de l'extraction de sous-chaîne indiquée dans d'autres réponses, vous pouvez également utiliser le remplacement de sous-chaîne. Compte tenu du dossier:

fn="XY TD-11212239.pdf"

Puis remplacement de la sous-chaîne de:

fn_new=${fn//*TD-/}

Fera également ce que vous voulez.

2
David C. Rankin
$ s='XY TD-11212239.pdf'
$ echo "${s#XY TD-}"
11212239.pdf

Si votre objectif est d'effectuer un renommage en masse:

while IFS= read -r -d '' filename; do
  mv "$filename" "${filename#XY TD-}"
done < <(find . -type f -name 'XY TD-*' -print0)

Notez que <() est une extension bash non présente dans POSIX sh. Vous pouvez le remplacer par un pipeline de la forme find ... | while.

De même, -print0 Est une extension GNU non présente dans la recherche POSIX. POSIX find ne fournit aucun moyen équivalent de localiser les fichiers qui est sûr pour les noms contenant des retours à la ligne, ce qui rend son remplacement difficile.

1
Charles Duffy