Extraer parte de una línea a una cadena en particular

Extraer parte de una línea a una cadena en particular

Supongamos que tengo un archivo con líneas como:

/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt
/foo/bar/bin/other/stuff/here

¿Hay alguna manera de extraer parte de las líneas hasta bin. Quiero decir, supongamos que esas líneas están en file.txtentonces

$ <some_command> file.txt 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/
/foo/bar/bin/

Respuesta1

Hay muchas maneras de hacer esto. Aquí están algunas:

# greedily caputure up to the last slash
grep -o '.*/bin/' file.txt
# remove all non-slash chars from the end of each line
sed 's#\(/bin/\).*$#\1#' file.txt
# using slash as a delimiter, blank out the last field
awk -F/ -v OFS=/ '{for (i=1; i<=NF; i++) if ($i == "bin") {NF=i; break}} 1' file.txt

Respuesta2

Una forma bash pura:

while read -n line
do
    [[ $line =~ /bin/ ]] && printf "%s\n" "${line/%\/bin\/*//bin/}"
done

Respuesta3

¿Qué, sin Perl?

perl -ne 's#/bin\K.*## && print' file

si sabes esotodolíneas contienen el patrón que desea, puede simplificar a:

perl -pe 's#/bin\K.*##' file

Es \Kuna expresión PCRE que significa "ignorar todo antes de \K".


También puedes hacer cosas como

awk -F"/bin" '{print $1FS}' file

Eso establece el delimitador de campo de awk ( FS) en /biny luego imprime el primer campo y el valor de FS(que es /bin). Ése, nuevamente, supone que quieres cada línea. Si no, usa este en su lugar:

awk -F"/bin" '($2){print $1FS}' file

Respuesta4

Junto con otras buenas respuestas, también puede probar lo siguiente que se asegurará de que todo lo que haya después /bin/no se imprima:

grep -Po ".*/(?<=/bin/)" file

Ejemplo:

$ cat test_file 
/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt/home

$ grep -Po ".*/(?<=/bin/)" test_file 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/

Aquí estamos usando elPCREcon una mirada positiva hacia atrás (?<=/bin/)para asegurarnos de que solo lleguemos hasta donde finalmente /llegamos ./bin/

información relacionada