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
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
Si vous coupez off les extrémités des chaînes, dirname
pourrait 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
$ _
bash
name__Vous pouvez utiliser le paramètre expansion dans bash
name__, dans ce cas
${parameter%Word}
où Word
est /*
${parameter##Word}
où Word
est */
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.
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 $
.
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é.
Solution classique avec awk
name__, 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 NF
variable):
$ 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 awk
name __, ce qui permettra d'économiser de la plomberie, mais rendra la portion de awk
plus détaillée:
mypath="xxx/xxxx/xxxxx/yyy" awk 'BEGIN{OFS=FS="/"; sub(/\/([^\/]*)$/,"",ENVIRON["mypath"]);print(ENVIRON["mypath"]) };'
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