Como imprimir apenas uma primeira correspondência de cada linha?

5

Eu tenho um arquivo assim:

asd 123 aaa wrqiqirw 123
123 itiewth 123 asno 123
123 132 123 123 123
boagii 123 asdnojaneoienton 123

A saída esperada é:

123
123
123
123

Vou precisar procurar padrões via regex. Existe alguma maneira de implementar uma coisa dessas?

    
por Andrew 15.03.2017 / 11:00

7 respostas

7

Com pcregrep , com um padrão como 12*3 :

pcregrep -o1 '(12*3).*'

Com pcregrep ou GNU grep -P :

grep -Po '^.*?\K12*3'

( pcregrep trabalha com bytes mais que caracteres, enquanto o GNU grep funcionará em caracteres conforme definido na localidade atual (e você deve certificar-se de que a entrada contém texto válido na localidade atual)).

Observe que o GNU grep não imprime nada se o padrão corresponder à string vazia.

    
por 15.03.2017 / 12:40
3
sed -e '
   /\n/{P;d;}
   s/12*3/\n&\n/;D
' < inoutfile
    
por 15.03.2017 / 11:56
3

Em Perl, simplesmente

perl -lne 'print $& if /\d+/' inputfile

ou de stdin:

echo foo 123 bar 456 doo 789 | perl -lne 'print $& if /\d+/'
123

O regex \d+ corresponderá a qualquer sequência de números consecutivos e $& refere-se à sequência correspondente.

    
por 15.03.2017 / 12:25
3

POSIXLY:

LC_ALL=C sed -e 's/.*\(123\).*//' <file

LC_ALL-C é necessário aqui para evitar que sed falhe ou produza resultados inesperados se o arquivo contiver caracteres inválidos em sua localidade atual.

Também produz uma entrada em uma linha, mas corresponde ao último , não ao primeiro .

Para combinar o primeiro com o GNU sed e o PCRE:

LC_ALL=C sed -E 's/.*?(123).*//'

( -E para RE estendido estará na próxima versão do POSIX)

    
por 15.03.2017 / 11:08
3

Apenas um grep deve ser suficiente para trazer correspondências de 123 em todas as linhas.
Não faz sentido se o jogo for o primeiro, o meio ou o final.
Você pede 123 você obtém 123 se estiver na linha (a menos que sua pergunta não seja expressa corretamente e você exija algo diferente)

$ grep -wo '123' file # -w: word match  -o : return only matched string instead of the whole line (default grep operation)

Caso você precise capturar com regex o primeiro número de cada linha (qualquer número - qualquer tamanho), então isso fará o trabalho:

cat <<EOF >file1
asd 111 777 aaa wrqiqirw 123
333 123 itiewth 123 asno 123
4444 111 123 123 567
boagii what 666 asdnojaneoienton 123
EOF
grep -Po '^[0-9]+|^.*?\K[0-9]+' file1
#output
111
333
4444
666
    
por 15.03.2017 / 12:02
2

Com grep em todas as linhas:

while IFS= read -r line; do printf '%s\n' "$line" | grep -o 123 | head -1; done < filename

Isto é:

  • While loop para verificar cada linha separadamente.
  • grep -o para obter apenas a correspondência em vez da linha inteira com correspondências.
  • head -1 para receber apenas a primeira correspondência e não as seguintes.
por 15.03.2017 / 11:33
1

com awk

re='12*3' awk '{match($0, ENVIRON["re"])}; RSTART{print(substr($0, RSTART, RLENGTH))}' file
    
por 15.03.2017 / 21:19