Comment couper une chaîne à partir d’une chaîne

Mon script obtient cette chaîne par exemple:

/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file 

Disons que je ne sais pas combien de temps la chaîne jusqu’à la /importance .

Je veux une nouvelle variable qui ne gardera que le /importance/lib1/lib2/lib3/file de la chaîne complète.

J’ai essayé d’utiliser sed 's/.*importance//' mais cela me donne le chemin sans importance ….

Voici la commande dans mon code:

 find  -name file | sed 's/.*importance// 

Je ne suis pas familier avec le regex, alors j’ai besoin de votre aide s’il vous plaît 🙂

Désolé mes amis, je me trompe juste à propos de ma question, je n’ai pas besoin du /importance/lib1/lib2/lib3/file output /importance/lib1/lib2/lib3/file mais /importance/lib1/lib2/lib3 sans / file dans la sortie.

Pouvez-vous m’aider?

J’utiliserais awk :

 $ echo "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file" | awk -F"/importance/" '{print FS$2}' importance/lib1/lib2/lib3/file 

Ce qui est le même que:

 $ awk -F"/importance/" '{print FS$2}' <<< "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file" importance/lib1/lib2/lib3/file 

C'est-à-dire que nous définissons le séparateur de champ sur /importance/ , de sorte que le premier champ est ce qui le précède et le second est ce qui vient après. Pour imprimer /importance/ lui /importance/ même, nous utilisons FS !

Tous ensemble, et pour l'enregistrer dans une variable, utilisez:

 var=$(find  -name file | awk -F"/importance/" '{print FS$2}') 

Mettre à jour

Je n'ai pas besoin du /importance/lib1/lib2/lib3/file output /importance/lib1/lib2/lib3/file mais de /importance/lib1/lib2/lib3 sans / file dans la sortie.

Ensuite, vous pouvez utiliser quelque chose comme dirname pour obtenir le chemin sans le nom lui-même:

 $ dirname $(awk -F"/importance/" '{print FS$2}' <<< "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file") /importance/lib1/lib2/lib3 

Au lieu de substituer tout à rien avec rien, remplacez par /importance :

 ~$ echo $var /dir1/dir2/dir3.../importance/lib1/lib2/lib3/file ~$ sed 's:.*importance:/importance:' <<< $var /importance/lib1/lib2/lib3/file 

Comme noté par @lurker, si l’ importance peut être dans un dir , vous pouvez append / s pour être sûr:

 ~$ sed 's:.*/importance/:/importance/:' <<< "/dir1/dirimportance/importancedir/..../importance/lib1/lib2/lib3/file" /importance/lib1/lib2/lib3/file 

Avec GNU sed:

 echo '/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file' | sed -E 's#.*(/importance.*)#\1#' 

Sortie:

 / importance / lib1 / lib2 / lib3 / fichier

pur bash

 kent$ a="/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file" kent$ echo ${a/*\/importance/\/importance} /importance/lib1/lib2/lib3/file 

outil externe: grep

 kent$ grep -o '/importance/.*' <<<$a /importance/lib1/lib2/lib3/file 

J’ai essayé d’utiliser sed 's/.*importance//' mais cela me donne le chemin sans importance ….

Tu étais très proche. Il suffisait de remplacer l’ importance :

 sed 's/.*importance/importance/' 

Cependant, j’utiliserais l’ extension de modèle intégrée à Bash. C’est beaucoup plus efficace et plus rapide.

Le modèle d’expansion ${foo##pattern} dit de prendre la variable shell ${foo} et de supprimer le plus gros motif de globalisation correspondant du côté gauche de la variable shell:

 file_name="/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file" file_name=${file_name##*importance} 

En supprimant le /file à la fin, vous demandez:

 echo '' | sed -r 's#.*(/importance.*)/[^/]*#\1#' 
  • Entrée /dir1/dir2/dir3.../importance/lib1/lib2/lib3/file
  • Retourne: /importance/lib1/lib2/lib3

Voir ce tutoriel ” Groupes de correspondance “.