web-dev-qa-db-fra.com

Script bash Ubuntu: comment diviser le chemin par la dernière barre oblique?

J'ai un fichier (appelé par exemple list.txt) qui contient des chemins d'accès relatifs aux fichiers, un chemin par ligne, c'est-à-dire quelque chose comme ceci:

foo/bar/file1
foo/bar/baz/file2
goo/file3

Je dois écrire un script bash qui traite un chemin à la fois, le divise à la dernière barre oblique, puis lance un autre processus en lui fournissant les deux parties du chemin sous forme d'arguments. Jusqu'à présent, je n'ai que la partie en boucle:

for p in `cat list.txt`
do
   # split $p like "foo/bar/file1" into "foo/bar/" as part1 and "file1" as part2
   inner_process.sh $part1 $part2
done

Comment puis-je me séparer? Cela fonctionnera-t-il dans le cas dégénéré lorsque le chemin ne comporte pas de barre oblique?

THX

40
I Z

Utilisez basename et dirname, c'est tout ce dont vous avez besoin.

part1=`dirname "$p"`
part2=`basename "$p"`
89
piokuc

Une méthode correcte à 100% et qui est sûre pour les noms de fichiers comportant des espaces ou des symboles amusants (à condition que inner_process.sh les traite correctement, mais c'est une autre histoire):

while read -r p; do
    [[ "$p" == */* ]] || p="./$p"
    inner_process.sh "${p%/*}" "${p##*/}"
done < list.txt

et il ne crée pas dirname et basename (dans les sous-shell) pour chaque fichier.

La ligne [[ "$p" == */* ]] || p="./$p" est ici juste au cas où $p ne contiendrait aucune barre oblique, alors il y ajouterait ./.

Voir la section Shell Parameter Expansion dans le Manuel de référence Bash pour plus d'informations sur les symboles % et ##.

12
gniourf_gniourf

Pour répondre à la critique de @ gniourf_gniourf sur la réponse de @ piokuc tout en restant concise et simple (sinon aussi efficace):

part1=`dirname "$p"`
part2=`basename "$p"`

(J'aurais répondu dans un commentaire mais c'est syntaxiquement impossible.)

4
Gordon

Excellente solution de cette source

p=/foo/bar/file1
path=$( echo ${p%/*} )
file=$( echo ${p##/*/} )

Cela fonctionne aussi avec des espaces dans le chemin!

0
Phil Roggenbuck