bash: comment renvoyer les extensions de fichier?

Je veux écrire un script pour ne renvoyer que lextension du nom du fichier dentrée. Par exemple, textfile.txt doit renvoyer txt.

Je suis nouveau sur Linux et bash, et je « m essayer dapprendre à écrire des scripts de base. Merci!

Commentaires

  • Voir aussi stackoverflow.com/questions/965053/…
  • Quelle est lextension du fichier linux-4.2.3.tar.xz que vous pouvez télécharger depuis kernel.org ? Quelle est lextension du fichier /bin/bash qui est certainement disponible sur votre système? Vous voyez, le concept d  » extension de fichier  » est assez étranger sous Linux. La partie après le point na que très peu dimportance pour le système – cest plutôt un indice pour lutilisateur sur ce quil pourrait attendre de ce fichier. Et ce signal peut mentir ou être faux.

Réponse

Le shell, bash par exemple, a beaucoup de fonctionnalités de manipulation de chaînes . Lun deux vous permet de tout supprimer jusquà un modèle donné:

${VAR##GLOB} 

La syntaxe ci-dessus supprime tout de la variable $VAR jusquà la première correspondance du glob GLOB. Donc, pour imprimer lextension dun fichier sans son nom, vous pouvez faire:

$ file="file.txt" $ echo ${file##*.} txt 

Notez que cela peut également traiter plus dune « extension »:

$ file="file.new.txt" $ echo ${file##*.} txt 

Si vous ne le souhaitez pas, utilisez un # à la place, ce qui supprimera la correspondance la plus courte à la place des plus longs:

$ echo ${file#*.} new.txt 

Maintenant, pour exécuter ceci sur tous les fichiers dun répertoire, vous pouvez faire:

$ ls file.avi file.pdf file.png file.txt $ for file in *; do echo "$file : ${file##*.}"; done file.avi : avi file.pdf : pdf file.png : png file.txt : txt 

Et, par souci dexhaustivité, vous pouvez également obtenir le nom du fichier sans son extension en utilisant ${file%.*}:

$ for file in *; do echo "$file : ${file##*.} : ${file%.*}"; done file.avi : avi : file file.pdf : pdf : file file.png : png : file file.txt : txt : file 

Commentaires

  • cela ne ‘ t fonctionne pas pour des choses comme foo / .git / bar / baz je suppose que vous pourriez faire echo test.txt | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘. ‘ ‘ {print $ NF} ‘
  • @PaulM que voulez-vous dire? Ce ‘ est un fichier sans extension, quespérez-vous en tirer?
  • echo  » / foo /var/.git/foo/bar.bz » | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘. ‘ ‘ {print $ NF} ‘ == > > bz
  • @PaulM file="/foo/var/.git/foo/bar.bz"; echo "${file##*.}": bz. Je ne vois ‘ aucun problème.

Réponse

Avec extension des paramètres :

$ x="textfile.txt" $ echo ${x##*.} txt 

Le ${parameter##word} motif supprime le plus grand préfixe correspondant à word (tout sauf la fin du fichier).

Réponse

Un script bash très simple qui pourrait faire ce que vous voulez serait le suivant:

#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}" 

Le script est appelé comme script.sh test.txt, et ce quil fait est

  • il imprime $1 sur stdout. $1 est le premier paramètre donné au script, dans ce cas test.txt.

  • la sortie stdout de echo est envoyée vers stdin pour awk qui divise la chaîne (test.txt) sur . puis il imprime le dernier élément du fractionnement (txt dans ce cas).

Juste une petite remarque, cela peut être fait avec un one-liner car cest « une tâche assez simple:

echo test.txt | awk -F "." "{print $NF}" 

Commentaires

  • Vous devez ajouter des guillemets autour de $1, ou vous risquez de casser les noms de fichiers contenant des espaces, etc.
  • cela ne ‘ t fonctionne pour des choses comme foo / .git / bar / baz Je suppose que vous pourriez faire echo test.txt | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘.’ ‘ {print $ NF} ‘

Réponse

#!/bin/bash my_file=`basename "$1"` # get full file name as a script parameter and strip the path my_extension="${my_file##*.}" my_file="${my_file%.*}" # will return base file name before the extension echo "$my_file" echo "$my_extension" 

Exécuter:

./script.sh index.html 

Sortie:

index html 

Plus dinformations: Extension des paramètres du shell | gnu.org

Réponse

Pour ce faire, il y a plusieurs mises en garde à prendre en compte:

  • Le fichier foo.d/bar na pas dextension, ce nest pas un fichier foo avec un .d/bar extension.
  • vous pouvez également considérer que .bashrc na pas dextension
  • Le . et .. les fichiers de répertoires spéciaux devraient probablement être traités spécialement et considérés comme nayant aucune extension.
  • quelle est lextension pour file.tar.gz? gz ou tar.gz? Quen est-il de holiday.picture.jpg ou bash-4.4?
  • Que devez-vous renvoyer pour foo.d/? Vide ou d?

Ici, je « ferais:

#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done 

Commentaires

  • Excellente réponse gérant également les mises en garde habituelles et le code utile surtout en tant que fonction.

Réponse

Je « vais ajouter dautres options au cas où vous auriez sed ou Perl installé:

 #!/bin/bash ext=$(<<<"$1" sed -n "s/^[^.]*\.//p") printf "Extension: $ext\n" ext=$(<<<"$1" perl -ne "s/^.*?\.//&&print") printf "Extension: $ext\n" exit 0  
  • s/^[^.]*\.//p dans sed et s/^.*?\.//&&print dans perl: essayez de remplacer la séquence de caractères la plus courte par . suivi dun caractère . au début de la chaîne; si la substitution peut être effectuée, affichez le résultat de la substitution;
 % bash script.sh file.bin Extension: bin Extension: bin  

Réponse

Soyez prudent. Sous Unix / Linux (et MacOS), « lextension de nom de fichier » est simplement informative (si tant est que cela). Vous pouvez parfaitement avoir un script Perl appelé photo.gif, ou un fichier GIF nommé poem.txt. Ou même un fichier appelé some.txt.png.

Commentaires

  • It ‘ est tout aussi informatif dans MS Windows, il ‘ que le programme shell par défaut fait des hypothèses plus solides sur le couplage extension-contenu, et devrait-il y avoir un décalage entre la dénomination et le contenu, le tout commence généralement à crier des erreurs, la mauvaise chose.

Laisser un commentaire

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