web-dev-qa-db-fra.com

Couper tous les caractères après le dernier /

Comment puis-je couper tous les caractères après le dernier '/'?

Ce texte

xxxx/x/xx/xx/xxxx/x/yyyyy
xxx/xxxx/xxxxx/yyy

devrait revenir

xxxx/x/xx/xx/xxxx/x
xxx/xxxx/xxxxx
8
Josef Klimuk

Si vous voulez obtenir la "partie coupée"

yyy
yyyyy

Vous pouvez utiliser

sed 's|.*/||' 

par exemple.

echo "xxx/xxxx/xxxxx/yyy" | sed 's|.*/||'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|.*\/||'

sortie

yyy
yyyyy

(Remarque: Ceci utilise la possibilité de sed d'utiliser un séparateur autre que /, dans ce cas |, dans la commande s)


Si vous voulez obtenir le début de la chaîne:

xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x

Vous pouvez utiliser

sed 's|\(.*\)/.*|\1|'

par exemple.

echo "xxx/xxxx/xxxxx/yyy" | sed 's|\(.*\)/.*|\1|'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|\(.*\)/.*|\1|'

sortie

xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x
10
Félicien

Si vous coupez off les extrémités des chaînes, dirnamepourrait faire l'affaire:

$ dirname xxxx/x/xx/xx/xxxx/x/yyyyy
xxxx/x/xx/xx/xxxx/x
$ _

Si vous essayez d'isoler la dernière partie de la chaîne, utilisez echo /$(basename "$str").

$ str=xxxx/x/xx/xx/xxxx/x/yyyyy
$ echo /$(basename "$str")
/yyyyy
$ _
18
dsstorefile1

Extension du paramètre dans bashname__

Vous pouvez utiliser le paramètre expansion dans bashname__, dans ce cas

  • ${parameter%Word}Wordest /*
  • ${parameter##Word}Wordest */

Exemples:

Supprimer la dernière partie

$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf%/*}
xxx/xxxx/xxxxx

Ceci est décrit dans man bash:

${parameter%Word}
${parameter%%Word}
      Remove matching suffix pattern.  The Word is expanded to produce
      a pattern just as in pathname expansion.  If the pattern matches
      a  trailing portion of the expanded value of parameter, then the
      result of the expansion is the expanded value of parameter  with
      the  shortest  matching  pattern (the ``%'' case) or the longest
      matching pattern (the ``%%'' case) deleted.  If parameter  is  @
      or  *,  the  pattern  removal operation is applied to each posi‐
      tional parameter in turn, and the  expansion  is  the  resultant
      list.   If  parameter is an array variable subscripted with @ or
      *, the pattern removal operation is applied to  each  member  of
      the array in turn, and the expansion is the resultant list.

Supprimer tout sauf la dernière partie

$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf##*/}
yyy

Vous pouvez ajouter une barre oblique comme

$ echo /${asdf##*/}
/yyy

pour obtenir exactement ce que vous vouliez dans un cas particulier en fonction de la question modifiée. Mais la question a été modifiée par plusieurs personnes après cela et il n’est pas facile de savoir ce que vous voulez maintenant.

Ceci est décrit dans man bash:

${parameter#Word}
${parameter##Word}
      Remove matching prefix pattern.  The Word is expanded to produce
      a pattern just as in pathname expansion.  If the pattern matches
      the  beginning of the value of parameter, then the result of the
      expansion is the expanded value of parameter with  the  shortest
      matching  pattern  (the ``#'' case) or the longest matching pat‐
      tern (the ``##'' case) deleted.  If parameter is  @  or  *,  the
      pattern  removal operation is applied to each positional parame‐
      ter in turn, and the expansion is the resultant list.  If param‐
      eter  is  an array variable subscripted with @ or *, the pattern
      removal operation is applied to each  member  of  the  array  in
      turn, and the expansion is the resultant list.
15
sudodus

Une autre méthode consiste à utiliser grep pour n’afficher que la dernière barre oblique par ligne et ce qui suit:

$ grep -o '/[^/]*$' example.txt
/yyy
/yyyyy

Explication:

-o indique à grep d'afficher uniquement la partie correspondante de la ligne au lieu de la totalité de la ligne.

Le modèle /[^/]*$ correspond à une barre oblique littérale / suivie de tout caractère sauf une barre oblique [^/] autant de fois que * jusqu'à la fin de la ligne $.

9
Byte Commander

Juste parce que d’autres ont publié des réponses plus "saines", voici une question un peu ridicule:

rev | cut -d/ -f1 | rev

rev inverse les caractères de chaque ligne, par exemple. abcd/ef/g devient g/fe/dcba. Ensuite, cut découpe le premier segment. Finalement, c’est à nouveau inversé.

7
egmont

Solution classique avec awkname__, qui traite / en tant que séparateur de champ pour l'entrée et la sortie et définit le dernier champ sur chaîne vide (qui est en réalité "dereferencing" du nombre de champs NFvariable):

$ echo "xxx/xxxx/xxxxx/yyy"|awk  'BEGIN{OFS=FS="/"};{$NF="";print $0}'
xxx/xxxx/xxxxx/

Plus court, comme fedorqui souligné dans les commentaires:

$ echo "xxx/xxxx/xxxxx/yyy"|awk  'BEGIN{OFS=FS="/"};NF--'
xxx/xxxx/xxxxx/

Une variante serait d'insérer le chemin dans l'environnement d'exécution de awkname __, ce qui permettra d'économiser de la plomberie, mais rendra la portion de awkplus détaillée:

mypath="xxx/xxxx/xxxxx/yyy" awk  'BEGIN{OFS=FS="/"; sub(/\/([^\/]*)$/,"",ENVIRON["mypath"]);print(ENVIRON["mypath"]) };'
3
Sergiy Kolodyazhnyy

Ajout à la réponse d'Egmont parce que la question a été modifiée ...

Utilisez - complement si vous souhaitez supprimer le premier champ avec - f1.

echo "xxxx/x/xx/xx/xxxx/x/yyyyy"|rev|cut -d/ -f1 --complement|rev
xxxx/x/xx/xx/xxxx/x

echo "xxxx/x/xx/xx/xxxx/x/yyyyy"|rev|cut -d/ -f1|rev
yyyyy

En outre, la question n'est pas très claire sur ce qui devrait se passer avec des entrées ne contenant pas de barres obliques. xxxx => xxxx ou xxxx => rien

2
Ph3n0x