J'ai une simple exigence comme suit,
Je reçois les noms de fichiers avec le répertoire absolu.
Par exemple /home/parent/child/filename
Mon exigence est de supprimer le nom de fichier.
Ce que j'ai essayé, c'est:
awk -F "/" '{print $5}' input
qui fonctionne parfaitement.
Mais voici un codage difficile $5
qui peut différer si mon entrée a la structure suivante:
/home/parent/child1/child2/filename
Donc, il devrait être dynamique sans codage dur. Voici la logique:
Toujours prendre le dernier champ qui sera le nom du fichier (il faut donc vérifier à partir de l’inverse).
Quelqu'un peut-il m'aider avec la fonction awk substr ou toute autre fonction?
Utilisez le fait que awk
divise les lignes dans les champs en fonction d'un séparateur de champ, que vous pouvez définir. Par conséquent, en définissant le séparateur de champ sur /
, vous pouvez dire:
awk -F "/" '{print $NF}' input
comme NF
fait référence au nombre de champs de l’enregistrement en cours, l’impression $NF
signifie l’impression du dernier.
Donc, étant donné un fichier comme celui-ci:
/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename
Ce serait la sortie:
$ awk -F"/" '{print $NF}' file
filename
filename
filename
Dans ce cas, il vaut mieux utiliser basename
au lieu de awk
:
$ basename /home/parent/child1/child2/filename
filename
Si vous êtes ouvert à une solution Perl, voici une solution similaire à la solution awk de fedorqui:
Perl -F/ -lane 'print $F[-1]' input
-F/
spécifie /
comme séparateur de champ$F[-1]
est le dernier élément du tableau @F
autosplit
Une autre option consiste à utiliser bash
substitution de paramètre .
$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename
Cela devrait être un commentaire sur la réponse du nom de base mais je n'ai pas assez de point.
Si vous n'utilisez pas de guillemets doubles, basename
ne fonctionnera pas avec les chemins où il y a un caractère d'espace:
$ basename /home/foo/bar foo/bar.png
bar
ok avec guillemets ""
$ basename "/home/foo/bar foo/bar.png"
bar.png
exemple de fichier
$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3
$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3
Je sais que j'ai 3 ans de retard sur ça, mais ... vous devriez envisager une expansion des paramètres, elle est intégrée et plus rapide.
si votre entrée est dans une var, disons $ var1, faites juste ${var1##*/}
. Regardez ci-dessous
$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename
Comme 5 ans de retard, je sais, merci pour toutes les propositions, je le faisais de la manière suivante:
$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename
Heureux de remarquer qu'il y a de meilleures manières