J'ai un répertoire (avec des sous-répertoires), dont je veux trouver tous les fichiers qui ont une extension ".ipynb". Mais je veux que la commande "find" me renvoie simplement ces noms de fichiers sans l'extension.
Je connais la première partie:
find . -type f -iname "*.ipynb" -print
Mais comment puis-je obtenir les noms sans l'extension "ipynb"? Toutes les réponses grandement appréciées ...
Pour renvoyer uniquement les noms de fichiers sans l'extension, essayez:
find . -name "*.ipynb" -execdir sh -c 'printf "%s\n" "${0%.*}"' {} ';'
ou:
find "$PWD" -type f -iname "*.ipynb" -execdir basename {} .ipynb ';'
ou:
find . -type f -iname "*.ipynb" -exec basename {} .ipynb ';'
cependant, invoquer basename
sur chaque fichier peut être inefficace, donc @ CharlesDuffy la suggestion est:
find . -name '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +
En utilisant +
signifie que nous transmettons plusieurs fichiers à chaque instance de bash, donc si toute la liste tient dans une seule ligne de commande, nous n'appelons bash qu'une seule fois.
Pour imprimer le chemin complet et le nom de fichier (sans extension) sur la même ligne, essayez:
find . -name "*.ipynb" -exec sh -c 'printf "%s\n" "${0%.*}"' {} ';'
ou:
find "$PWD" -type f -iname "*.ipynb" -print | grep -o "[^\.]\+"
Pour imprimer le chemin d'accès complet et le nom de fichier sur des lignes distinctes:
find "$PWD" -type f -iname "*.ipynb" -exec dirname "{}" ';' -exec basename "{}" .ipynb ';'
Voici une solution simple:
find . -type f -iname "*.ipynb" | sed 's/\.ipynb$//1'
Perl One Liner
ce que vous voulez find . | Perl -a -F/ -lne 'print $F[-1] if /.*.ipynb/g'
Alors pas votre code
ce que vous ne voulez pas find . | Perl -a -F/ -lne 'print $F[-1] if !/.*.ipynb/g'
NOTE
Dans Perl vous devez mettre _ .
. Votre modèle serait donc .*.ipynb
Un autre moyen simple qui utilise basename
est:
find . -type f -iname '*.ipynb' -exec basename -s '.ipynb' {} +
En utilisant +
réduira le nombre d'appels de la commande ( manpage ):
-exec commande {} +
Cette variante de l'action -exec exécute la commande spécifiée sur les fichiers sélectionnés, mais la ligne de commande est créée en ajoutant à la fin chaque nom de fichier sélectionné; le nombre total d'appels de la commande sera bien inférieur au nombre de fichiers correspondants. La ligne de commande est construite de la même manière que xargs construit ses lignes de commande. Une seule instance de '{}' est autorisée dans la commande et (lorsque find est invoquée à partir d'un shell), elle doit être citée (par exemple, '{}') pour la protéger de l'interprétation par les shells. La commande est exécutée dans le répertoire de départ. Si une invocation avec le formulaire `+ 'renvoie une valeur non nulle comme état de sortie, alors find renvoie un état de sortie non nul. Si find rencontre une erreur, cela peut parfois entraîner une sortie immédiate, de sorte que certaines commandes en attente peuvent ne pas être exécutées du tout. Pour cette raison, -exec ma-commande ... {} + -quit peut ne pas entraîner l'exécution de ma-commande. Cette variante de -exec renvoie toujours true.
En utilisant -s
avec basename
s'exécute accepte plusieurs noms de fichiers et supprime un suffixe spécifié ( manpage ):
-a, --multiple
prendre en charge plusieurs arguments et traiter chacun comme un NOM
-s, --suffix = SUFFIXE
supprimer un SUFFIX arrière; implique -a
Si vous ne savez pas que l'extension est ou s'il y en a plusieurs, vous pouvez utiliser ceci:
find . -type f -exec basename {} \;|Perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'
et pour une liste de fichiers sans doublons (dont le chemin ou l'extension diffère à l'origine)
find . -type f -exec basename {} \;|Perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'|sort|uniq
find . -type f -iname "*.ipynb" | grep -oP '.*(?=[.])'
L'indicateur -o ne produit que la partie correspondante. L'indicateur -P correspond en fonction des expressions régulières Perl. Ceci est nécessaire pour rendre le lookahead(?=[.])
travail.
Si vous devez avoir le nom avec le répertoire mais sans l'extension:
find . -type f -iname "*.ipynb" -exec sh -c 'f=$(basename $1 .ipynb);d=$(dirname $1);echo "$d/$f"' sh {} \;
J'ai trouvé cela dans un basel oneliner qui simplifie le processus sans utiliser find
for n in *.ipynb; do echo "${n%.ipynb}"; done
S'il n'y a aucune occurrence de cette chaîne ".ipynb" sur un nom de fichier autre qu'un suffixe, vous pouvez essayer cette méthode plus simple en utilisant tr
:
find . -type f -iname "*.ipynb" -print | tr -d ".ipbyn"