Extrai substring usando expressão regular em um arquivo Unix

4

Eu tenho um arquivo com o conteúdo abaixo.

/ABC/RTE/AD_900_VOP_123/OPP
/ABC/RTE/TRE/AD_900_VOP_145/BBB
/ABC/RTE/AN_900_VFP_124/FBF
/ABC/RTE/HD_900_FOP_153/WEW
/ABD/RDV/AD_900_VOP_123/OPP
/ABC/RTE/WD_900_VOP_123/GRR/TRD
/ABC/RTE/RTD/AR_900_VOP_443/SDD

Como posso usar expressões regulares neste arquivo para que eu obtenha a saída como

AD_900_VOP_123
AD_900_VOP_145
AN_900_VFP_124
HD_900_FOP_153
AD_900_VOP_123
WD_900_VOP_123
AR_900_VOP_443
    
por g4ur4v 25.06.2013 / 18:13

6 respostas

7

Gnu grep

grep -oE '[[:alpha:]]+_[[:digit:]]+_[[:alpha:]]+_[[:digit:]]+' 

Use a sinalização perl-regex e as declarações look-behind e look-ahead para garantir que a correspondência esteja entre /

grep -oP '(?<=/)[[:alpha:]]+_[[:digit:]]+_[[:alpha:]]+_[[:digit:]]+(?=/)'
    
por 25.06.2013 / 18:17
2

Uma maneira com awk :

awk -F/ '{for(i=1;i<=NF;i++)$0=($i~/_/)?$i:$0}1' file
    
por 26.06.2013 / 03:37
2

IMHO Perl oferece a solução mais fácil e mais flexível:

perl -nE 'say $1 if m{/(\w+\d+\w+\d+)/};' input_file

Por favor, note que input_file é opcional: STDIN será filtrado se / quando o nome do arquivo de entrada não for informado.

    
por 13.01.2015 / 02:12
0

Isso deve fazer o que você precisa.

Conteúdo de tstfile.txt :

/ABC/RTE/AD_900_VOP_123/OPP
/ABC/RTE/TRE/AD_900_VOP_145/BBB
/ABC/RTE/AN_900_VFP_124/FBF
/ABC/RTE/HD_900_FOP_153/WEW
/ABD/RDV/AD_900_VOP_123/OPP
/ABC/RTE/WD_900_VOP_123/GRR/TRD
/ABC/RTE/RTD/AR_900_VOP_443/SDD

Comando para transformar tstfile.txt :

$ sed 's|.*/\([0-9_A-Z]\+900[0-9_A-Z]\+\)/.*||' tstfile.txt
AD_900_VOP_123
AD_900_VOP_145
AN_900_VFP_124
HD_900_FOP_153
AD_900_VOP_123
WD_900_VOP_123
AR_900_VOP_443

explicação

O texto acima extrai tudo o que toca o "900" até a primeira barra invertida encontrada no início de "900" (à esquerda do 9) e tudo até a primeira barra invertida no final de "900" ( à direita do último 0).

    
por 25.06.2013 / 18:26
0
sed 's|.*/\([^/]*_[^/]*\)/.*||
' <<\INPUT
/ABC/RTE/AD_900_VOP_123/OPP 
/ABC/RTE/TRE/AD_900_VOP_145/BBB 
/ABC/RTE/AN_900_VFP_124/FBF 
/ABC/RTE/HD_900_FOP_153/WEW 
/ABD/RDV/AD_900_VOP_123/OPP 
/ABC/RTE/WD_900_VOP_123/GRR/TRD 
/ABC/RTE/RTD/AR_900_VOP_443/SDD
INPUT

Isso removerá a segunda até a última ocorrência de / imediatamente antes de um caractere _ em uma linha, salvará tudo entre lá e a próxima ocorrência de / e, em seguida, removerá o restante.

O comando acima imprime ...

AD_900_VOP_123 
AD_900_VOP_145 
AN_900_VFP_124 
HD_900_FOP_153 
AD_900_VOP_123 
WD_900_VOP_123 
AR_900_VOP_443
    
por 13.01.2015 / 05:55
0

As partes que você não deseja têm uma barra e três caracteres.

A parte que você deseja manter também começa com uma barra e tem mais de três caracteres, mas o terceiro caractere é um sublinhado, então excluímos todas as partes que parecem com /XXX , mas não /XX_

Isso deixa a barra inicial da parte que queremos manter, então, finalmente, também excluímos essa barra.

sed 's|/..[^_]||g; s|^/||' </tmp/f1

Explicação:

O comando sed é composto de dois s (comandos substitutos) separados por ; . Como temos barra na expressão regular, eu uso s|...|...| em vez do s/.../.../ regular

Ambos os comandos substitutos têm a segunda parte vazia - substitua por nada = delete essa parte. O primeiro usa um g para global, em outras palavras, faça isso repetidamente até que não haja nada para substituir.

O [^_] corresponde a qualquer coisa, exceto um sublinhado. T

    
por 13.01.2015 / 12:41