Extrai parte de uma linha até uma string específica

3

Vamos supor que eu tenha um arquivo com linhas como:

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

Existe uma maneira de extrair parte das linhas até bin . Quero dizer, suponha que essas linhas estejam em file.txt then

$ <some_command> file.txt 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/
/foo/bar/bin/
    
por Ten-Coin 10.03.2015 / 15:36

5 respostas

8

Existem várias maneiras de fazer isso. Aqui estão alguns:

# 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/\).*$##' 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
    
por glenn jackman 10.03.2015 / 15:41
4

Um modo bash puro:

while read -n line
do
    [[ $line =~ /bin/ ]] && printf "%s\n" "${line/%\/bin\/*//bin/}"
done
    
por muru 10.03.2015 / 16:29
4

O que, não Perl?

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

Se você souber que todas as linhas contêm o padrão desejado, simplifique para:

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

O \K é uma expressão PCRE que significa "ignorar tudo antes do \K ".

Você também pode fazer coisas como

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

Isso define o delimitador de campo do awk ( FS ) como /bin e, em seguida, imprime o primeiro campo e o valor de FS (que é /bin ). Aquele, novamente, assume que você quer cada linha. Se não, use este em vez disso:

awk -F"/bin" '(){print FS}' file
    
por terdon 10.03.2015 / 17:01
3

Em python:

python3 -c "for l in open('f').readlines(): print(l[:l.find('/bin')+5])"

/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/

onde f é o caminho para o arquivo (entre aspas simples).

    
por Jacob Vlijm 10.03.2015 / 15:42
2

Juntamente com outras boas respostas, você também pode tentar o seguinte, que garante que o que houver após /bin/ não seja impresso:

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

Exemplo:

$ 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/

Aqui estamos usando o PCRE com lookbehind (?<=/bin/) positivo para garantir que levamos apenas até o / , onde temos /bin/ enfim.

    
por heemayl 10.03.2015 / 15:59