¿Cómo corto todos los caracteres después del último '/'?
Este texto
xxxx/x/xx/xx/xxxx/x/yyyyy
xxx/xxxx/xxxxx/yyy
debería volver
xxxx/x/xx/xx/xxxx/x
xxx/xxxx/xxxxx
fuente
¿Cómo corto todos los caracteres después del último '/'?
Este texto
xxxx/x/xx/xx/xxxx/x/yyyyy
xxx/xxxx/xxxxx/yyy
debería volver
xxxx/x/xx/xx/xxxx/x
xxx/xxxx/xxxxx
Si quieres obtener la "parte cortada"
yyy
yyyyy
Puedes usar
sed 's|.*/||'
p.ej.
echo "xxx/xxxx/xxxxx/yyy" | sed 's|.*/||'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|.*\/||'
salida
yyy
yyyyy
(Nota: Esto usa la capacidad de sed para usar un separador que no sea /, en este caso |, en el comando s)
Si desea obtener el comienzo de la cadena:
xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x
Puedes usar
sed 's|\(.*\)/.*|\1|'
p.ej.
echo "xxx/xxxx/xxxxx/yyy" | sed 's|\(.*\)/.*|\1|'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|\(.*\)/.*|\1|'
salida
xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x
#
lugar de /
. También puede utilizar la opción -r
si no desea escapar `\` cada carácter especial: sed -r 's#(^.*)/.*$#\1#'
.
Si estás cortando fuera de los extremos de las cuerdas, dirname
podría encajar el proyecto de ley:
$ dirname xxxx/x/xx/xx/xxxx/x/yyyyy
xxxx/x/xx/xx/xxxx/x
$ _
Si está intentando aislar la última parte de la cadena, use echo /$(basename "$str")
.
$ str=xxxx/x/xx/xx/xxxx/x/yyyyy
$ echo /$(basename "$str")
/yyyyy
$ _
dirname
y basename
no son ampliamente conocidos, pero sed
y lo awk
son.
cat text | basename
lo tanto no funcionarán. Entonces, una solución adecuada a la pregunta de OP usando dirname
e basename
involucraría, xargs
etc.
bash
Puede usar la expansión de parámetros en bash
, en este caso
${parameter%word}
donde word
esta/*
${parameter##word}
donde word
esta*/
Eliminar la última parte
$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf%/*}
xxx/xxxx/xxxxx
Esto se describe en 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.
Eliminar todo excepto la última parte
$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf##*/}
yyy
Puedes agregar una barra como esta
$ echo /${asdf##*/}
/yyy
para obtener exactamente lo que quería en una instancia particular de acuerdo con la pregunta editada. Pero la pregunta ha sido editada por varias personas después de eso y no es fácil saber lo que quieres ahora.
Esto se describe en 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.
Otra forma es usar grep
para mostrar solo la última barra por línea y lo que sigue:
$ grep -o '/[^/]*$' example.txt
/yyy
/yyyyy
Explicación:
-o
le dice grep
que solo muestre la parte coincidente de la línea en lugar de la línea completa.
El patrón /[^/]*$
coincide con una barra diagonal /
seguida de cualquier carácter, excepto una barra [^/]
cualquier cantidad de veces *
hasta el final de la línea $
.
Solo porque otros han publicado más respuestas "sensatas", aquí hay una respuesta un tanto tonta:
rev | cut -d/ -f1 | rev
rev
invierte los caracteres en cada línea, por ejemplo, se abcd/ef/g
convierte en g/fe/dcba
. Luego cut
corta el primer segmento. Finalmente se invierte nuevamente.
Solución clásica con awk
, que trata /
como un separador de campo tanto para la entrada como para la salida y establece el último campo en una cadena vacía (que realmente es "desreferenciar" de la NF
variable número de campos ):
$ echo "xxx/xxxx/xxxxx/yyy"|awk 'BEGIN{OFS=FS="/"};{$NF="";print $0}'
xxx/xxxx/xxxxx/
Más breve , como señaló fedorqui en los comentarios:
$ echo "xxx/xxxx/xxxxx/yyy"|awk 'BEGIN{OFS=FS="/"};NF--'
xxx/xxxx/xxxxx/
Una variación de eso sería colocar la ruta en awk
el entorno de ejecución de la versión, lo que ahorrará en fontanería pero hará que la awk
porción sea más detallada:
mypath="xxx/xxxx/xxxxx/yyy" awk 'BEGIN{OFS=FS="/"; sub(/\/([^\/]*)$/,"",ENVIRON["mypath"]);print(ENVIRON["mypath"]) };'
NF--
? De esta manera usted avoud el print
bla bla.
Agregando a la respuesta de egmont porque la pregunta ha sido editada ...
Use --complement si desea eliminar el primer campo con -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
Además, la pregunta no es clara sobre qué debería suceder con las entradas que no contienen barras. xxxx => xxxx o xxxx => nada
--complement
opción antes y la página de manual es circular. Complemento significa complemento. Encontré un bonito tutorial de corte que lo cubre en yourownlinux.com/2015/05/... Es como -v
en grep
. Dame todo, excepto lo que coincida.
-f2-
es una forma más simple para -f1 --complement
.
basename
ydirname
hacer esto ya./
" se convirtió en "¿Cómo corté todos los caracteres después del último '/'?" que es un cambio de fraseo que conserva razonablemente el significado, IMO. En todo caso, sentí que la parte "omitir lo que es ..." es ambigua: los ejemplos parecen mantener lo que está antes del/
. El ejemplo, lo deja claro, de todos modos.