84 votes

Supprimer une partie du chemin sous Unix

J'essaie de supprimer une partie du chemin dans une chaîne de caractères. J'ai le chemin :

/path/to/file/drive/file/path/

Je souhaite supprimer la première partie /path/to/file/drive et produire le résultat :

file/path/

Note : J'ai plusieurs chemins dans une boucle while, avec le même /path/to/file/drive dans chacun d'entre eux, mais je cherche simplement le "comment faire" pour supprimer la chaîne souhaitée.

J'ai trouvé quelques exemples, mais je n'arrive pas à les faire fonctionner :

echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:\2:'
echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:2'

\2 étant la deuxième partie de la chaîne, il est clair que je fais quelque chose de mal... Peut-être y a-t-il un moyen plus simple ?

116voto

ACK_stoverflow Points 487

Si vous souhaitez supprimer un certain NUMÉRO des composants du chemin, vous devez utiliser cut con -d'/' . Par exemple, si path=/home/dude/some/deepish/dir :

Pour retirer les deux premiers composants :

# (Add 2 to the number of components to remove to get the value to pass to -f)
echo $path | cut -d'/' -f4-
# output:
# some/deepish/dir

Pour conserver les deux premiers éléments :

echo $path | cut -d'/' -f-3
# output:
# /home/dude

Pour retirer les deux derniers composants ( rev inverse la chaîne) :

echo $path | rev | cut -d'/' -f4- | rev
# output:
# /home/dude/some

Pour conserver les trois derniers éléments :

echo $path | rev | cut -d'/' -f-3 | rev
# output:
# some/deepish/dir

Ou si vous souhaitez supprimer tout ce qui se trouve avant un composant particulier, sed fonctionnerait :

echo $path | sed 's/.*\(some\)/\1/g'
# output:
# some/deepish/dir

Ou après un composant particulier :

echo $path | sed 's/\(dude\).*/\1/g'
# output:
# /home/dude

C'est encore plus facile si vous ne voulez pas conserver le composant que vous spécifiez :

echo $path | sed 's/some.*//g'
# output:
# /home/dude/

Et si vous voulez être cohérent, vous pouvez également faire correspondre la barre oblique finale :

echo $path | sed 's/\/some.*//g'
# output:
# /home/dude

Bien sûr, si vous faites correspondre plusieurs barres obliques, vous devez changer l'option sed délimiteur :

echo $path | sed 's!/some.*!!g'
# output:
# /home/dude

Notez que ces exemples utilisent tous des chemins d'accès absolus, vous devrez jouer pour les faire fonctionner avec des chemins d'accès relatifs.

82voto

evil otto Points 6069

Pour ce faire, vous pouvez également utiliser l'expansion des variables du shell POSIX.

path=/path/to/file/drive/file/path/
echo ${path#/path/to/file/drive/}

Les #.. supprime la première chaîne de caractères correspondante lorsque la variable est développée ; ceci est particulièrement utile si vos chaînes de caractères se trouvent déjà dans des variables shell, comme si vous utilisiez une variable for boucle. Vous pouvez également supprimer les chaînes de caractères correspondantes (par exemple, une extension) à la fin d'une variable, en utilisant la fonction %... . Voir le bash pour plus de détails.

32voto

glenn jackman Points 69748

Si vous ne voulez pas coder en dur la partie que vous retirez :

$ s='/path/to/file/drive/file/path/'
$ echo ${s#$(dirname "$(dirname "$s")")/}
file/path/

12voto

Jonathan Callen Points 3218

Une façon de procéder avec sed est la suivante

echo /path/to/file/drive/file/path/ | sed 's:^/path/to/file/drive/::'

5voto

Fritz Points 567

Si vous souhaitez supprimer les N premières parties du chemin Vous pouvez bien sûr utiliser N appelle à dirname comme dans Réponse de Glenn mais il est probablement plus facile d'utiliser le globbing :

path=/path/to/file/drive/file/path/
echo "${path#*/*/*/*/*/}"   #  file/path/

En particulier, ${path#*/*/*/*/*/} moyens "retour $path moins le préfixe le plus court contenant 5 barres obliques" .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X