Comment supprimer lextension de nom de fichier dune liste de noms de fichiers dans bash

Jessaie de supprimer lextension de nom de fichier dune liste de fichiers que jai générés avec ce qui suit script bash:

 #!/bin/bash file_list=$(find . -type f) #assuming that the files are stored in the same directory trimmed_file_list=$(printf "%s\n" "${file_list[@]%.*}") printf "%s\n" "${trimmed_file_list[@]}" 

Cette extension supprime lextension de la dernière entrée de la liste, mais pas de lune des précédentes.

Par exemple, je veux que la liste suivante:

 file1.pdf file2.pdf file3.png 

Pour devenir

 file1 file2 file3 

Mais à la place, jobtiens:

 file1.pdf file2.pdf file3 

Je préfère ne pas faire cela en boucle, jaimerais utiliser lexpansion des paramètres. Je veux éviter de couper parce que je veux seulement supprimer la dernière extension du fichier.

Il y a un bon nombre de sujets sur lexpansion des paramètres et il semble que bash pourrait sétouffer avec find » lutilisation des nouvelles lignes … Je ne suis vraiment pas sûr. Si un autre des sujets préexistants explique ce problème, je ne saisis pas complètement ce qui se passe.

Sujets qui semblent liés mais ne semblent pas résoudre mon problème:

Commentaires

  • Votre titre mentionne des tableaux, mais il ny a pas de tableau dans votre code.
  • @Kusalananda Merci! Je ‘ men suis rendu compte depuis que jai posé la question. Je suis toujours en train dapprendre 🙂
  • @Kusalananda Jai ‘ aller de lavant et modifier la question pour quelle corresponde plus étroitement au problème. Cela devrait empêcher des recherches Google erronées datteindre la page. Merci pour linformation!

Réponse

Vous pouvez tout faire en une seule commande.

find /path/to -type f -execdir bash -c "printf "%s\n" "${@%.*}"" bash {} + 

Commentaires

  • Merci! En fait, jai besoin de créer quelques copies du tableau, une pour un menu dont le nom de fichier a été modifié et une qui conservera la valeur dindex dorigine afin que je puisse appeler le fichier à partir du menu. Cest vraiment incroyable tout ce que bash peut faire! La possibilité de tout intégrer dans une seule commande mépate toujours! : D

Réponse

Je crois que vous voudriez créer un tableau au lieu dune chaîne:

IFS=$"\n" # split on newline only set -o noglob # disable the glob part file_list=($(find . -name "*.*" -type f)) 

Ou avec bash 4.4+, ne pas casser sur les chemins de fichiers avec des caractères de nouvelle ligne:

readarray -td "" file_list < <(find . -name "*.*" -type f -print0) 

Ensuite, lexpansion de vos paramètres devrait fonctionner, bien quici il serait plus logique dutiliser à nouveau une variable de tableau:

trimmed_file_list=("${file_list[@]%.*}") 

Dans votre exemple de code, vous créez une chaîne puis demander à lexpansion des paramètres de tout supprimer après le dernier caractère de point dans la chaîne complète.

Commentaires

  • Merci! Je le testerai dès que jarriverai à mon bureau le matin.
  • Cela suppose quaucun nom de fichier dans ce répertoire ne contient despaces ou de caractères globuleux.
  • @Wildcard, devrait être adressé par la dernière modification.
  • @Wildcard Merci pour le pointeur! Je ‘ m génère les fichiers qui sont déposés dans ce répertoire par programme, donc cela ne devrait pas ‘ être un problème.

Réponse

Votre code ninclut aucun tableau. De plus, il place une liste de noms de fichiers dans une chaîne, $file_list. Le contenu de la chaîne se terminera par file3.png et votre substitution de paramètre supprime .png de la chaîne, vous laissant avec une seule chaîne de noms de fichiers où le dernier nom de fichier na pas de suffixe de nom de fichier.

Mettre plusieurs objets séparés (chemins) dans une seule chaîne disqualifie automatiquement le script de fonctionner correctement pour les fichiers dont les noms contiennent des espaces (ou tout autre délimiteur utilisé par la chaîne). Lutilisation dun tableau naiderait pas car vous diviseriez toujours la sortie de find sur des espaces.


Pour couper lextension de tous les noms de fichiers des fichiers normaux dans ou sous le répertoire courant:

find . -type f -name "*.*" -exec sh -c " for pathname do printf "Would move %s to %s...\n" "$pathname" "${pathname%.*}" # mv -i "$pathname" "${pathname%.*}" done" sh {} + 

Ceci recherche les fichiers normaux dont les noms contiennent au moins un point. Les chemins daccès de ces fichiers sont introduits par lots dans un petit script shell qui les parcourt en boucle. Le script shell renomme les fichiers en supprimant le dernier point du nom de fichier et tout ce qui suit. La commande mv est commentée pour des raisons de sécurité.

La commande find agit comme un générateur de chemins pour le script shell interne, et nous sommes assurés de traiter correctement les chemins contenant des espaces, des nouvelles lignes et des tabulations. Il nest pas nécessaire de stocker la sortie des commandes dans des variables.

Si vous avez un tableau de chemins, éventuellement créé en utilisant

shopt -s globstar nullglob file_list=( **/*.* ) # get pathnames of files with dots in their names 

Alors vous seriez en mesure de sortir les chemins sans suffixes avec

printf "%s\n" "${file_list[@]%.*}" 

Je ne sais pas si cela vous aidera. Si vous voulez utiliser les chemins sans suffixes pour quelque chose , alors utiliser la sortie de la commande printf ci-dessus serait la mauvaise chose à faire (vous seriez de retour à ne plus gérer de chemin étrange). et la façon dont vous supprimez les suffixes de nom de fichier dépend de ce que vous aimeriez faire avec le résultat.

Connexes:

Commentaires

  • Merci! Votre maîtrise de la bash est très évidente! Je ‘ gratte toujours la surface … Merci davoir pris le temps daider 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *