Como combinar uma string exata usando 'sed'? Mas não a parte disso.

8

Eu tenho um arquivo de entrada FILE1.TXT como abaixo.

11 id1  
12  
13 AGE = 20  
14 NAME = NAME1  
15  
16 id2  
17  
18 AGE = 30  
19 NAME = NAME2  
.  
.  
.  
110 idXYZ  
111  
112 AGE = AGEXYZ  
113 NAME = NAMEXYZ  
114  
115 idZZZ  
116

Eu quero pesquisar todos os campos que pertencem a um Id e obter o valor para NAME

Eu consegui fazer um loop através de cada Id e formou o comando abaixo para cada Id , conforme necessário.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'

O problema aqui é que eu recebo a saída NAME1 , além disso, eu também recebo NAMEXYZ .

O que deve ser alterado para que eu tenha apenas NAME1 , mas não NAMEXYZ ?

Como solução alternativa, os comandos abaixo funcionam.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'|head -1

Existe algum 'switch' ou estou faltando alguma coisa?

    
por Vinay 03.03.2014 / 18:02

7 respostas

3

Se você souber os números de linha que deseja pesquisar (como sugere o seu Q), aperte o regex para não coincidir com linhas indesejadas.

Por exemplo, altere:

sed -n '/11/,/14/p' | grep NAME | awk -F "= " '{print $2}'

para

sed -n '/^11 /,/^14 /p' | grep NAME | awk -F "= " '{print $2}'

O ^ corresponderá ao início da linha e um espaço após o número garantirá que o número da linha específica será correspondido e você não processará blocos indesejados.

    
por 03.03.2014 / 18:09
4

Você pode usar o AWK

awk 'NR>=13 && NR<=17 && /NAME/{print $NF}' infile

Isto irá procurar linhas entre 13 e 17, em seguida, procure por Nome e, se for o caso, imprimirá a última palavra em Name = LastWord

    
por 03.03.2014 / 18:28
4

Use limites de palavras:

grep '\bNAME1\b'

corresponderia a NAME1 e não a NAME1XYZ ou XYZNAME1 .

Da mesma forma,

sed -n '/11\b/,/14\b/p'

não corresponde a linhas que contêm 111 e 142 .

EDIT: Parece que os números no arquivo de entrada são, na verdade, números de linha. Se for esse o caso, você poderia simplesmente dizer:

sed '11,14!d'

para obter as linhas desejadas.

    
por 03.03.2014 / 18:06
3

sed não é a ferramenta certa para esse trabalho. Use o awk, onde você pode especificar o ID que está procurando e imprimir o próximo NAME que aparecer.

awk -v id="id2" '
    $NF == id {have_id = 1} 
    have_id && $0 ~ /NAME/ {print $NF; exit}
' filename
    
por 03.03.2014 / 18:12
3

Você não precisa de nenhuma outra ferramenta para isso, sed irá lidar com tudo isso facilmente.

sed -nr '/11/,/14/{s/^.*NAME =\s*(\S*).*$//p}' <$infile

Isso deve fornecer apenas a primeira seqüência de caracteres que não são espaços em branco após a frase "NAME=" para cada linha na qual a frase é encontrada entre as linhas 11 e 14 de qualquer arquivo de entrada sed . p>     

por 04.03.2014 / 06:25
0

versão genérica não baseada no número da linha, mas na referência da id

sed -n '1h;1!H;
$ {
  x
  s/.*/&\^J/
: clean
#  put your ID pattern here in place of id9
  s/.*\(id9 *\n.*\)id[0-9]\{1,\} *\n.*//
  t clean
  s/.*NAME = \([^[:cntrl:]]*\)\n.*//
  p
  }' YourFile
  1. carregar o arquivo inteiro
  2. seção limpa não faz parte do grupo de id (recursivo)
  3. adicione o valor do conteúdo NAME no grupo
  4. imprima o resultado
por 06.03.2014 / 09:53
0

você pode imprimir as linhas que contêm padrão de correspondência usando sed da seguinte forma:

sed -n '/pattern/p'  Filename
  • -n - essas opções desativam essa impressão automática e só sed  produz saída quando explicitamente informado através do comando p .

  • p - imprimir

por 03.08.2016 / 11:56