Extrai parte de uma linha de um arquivo com sed

18

Quero ler uma parte de uma linha de um arquivo. Por exemplo:

POP3_SERVER_NAME = host local

Eu quero retornar apenas localhost, usando sed.

Este texto está na terceira linha. Eu faço isso para extrair a linha:

sed -n '3p' installation.sh

Como extraio apenas a localhostpeça?

Mercer
fonte

Respostas:

26

O awk pode ser uma ferramenta melhor aqui.

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

Procure linhas que contenham "POP3_SERVER_NAME"; imprima o último campo. Isso não depende de o POP3_SERVER_NAME estar sempre na linha 3, o que provavelmente é uma coisa boa.

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Dependendo do seu aplicativo, pode ser necessário tornar a expressão regular mais rigorosa. Por exemplo, convém corresponder apenas a linha que começa com POP3_SERVER_NAME.

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Usar sed é um pouco menos intuitivo. (Obrigado, estou ciente da ironia.) Aborde a linha que contém POP3_SERVER_NAME em qualquer lugar. Substitua uma sequência vazia por todo o texto do início da linha pelo espaço opcional após "=". Então imprima.

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat
Mike Sherrill 'Rechamada de gato'
fonte
2
O awkcomando é bom - mas apenas se você tiver espaços ao redor do =. Não vai funcionar POP3_SERVER_NAME=localhost.
Marcel Stör
2
@ Marcel, você pode alterar o delimitador usado pelos awkespaços para outra coisa usando -F. Por exemplo: -F "="será usado =como delimitador no caso mencionado.
mattpr
7

Substitua o pcomando por uma substituição que remove a parte indesejada da linha.

sed -n '3 s/^[^=]*= *//p' installation.sh

Convém corresponder a linha por palavra-chave e não por posição.

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh
Gilles 'SO- parar de ser mau'
fonte
5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

Ou se você tiver o conteúdo em um arquivo:

sed 's/.*= //' somefile.txt
localhost
Adam Siemion
fonte
ok, mas eu li no meu arquivo desta forma: sed -n '3p' installation.sh
Mercer
2
@ Mercer - veja as atualizações que adicionei à resposta.
slm
@ Adam Siemion - obrigado, mas como indicar o número da linha?
Mercer
5

Parece que você tem um arquivo de configuração. O que você poderia fazer é semelhante ao que Adam Siemeon / slm sugere:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

onde [^=]exclui todos os '=' personagens, +diz um ou mais do mesmo tipo de personagem, este seguido por um real =, \squalquer espaço em branco (incluindo guias \te novas linhas \n, \r\n, e espaços simples '', enquanto *meios zero ou mais do mesmo tipo , parênteses capturam o que está dentro para colocar as seqüências de caracteres correspondentes nos espaços reservados de substituição \ 1, \ 2, ..., \ n, $significa o final de uma linha, seguindo o padrão de substituição típico de: s/.../.../modifiers.A opção de linha de comando -rsignifica sintaxe regex estendida (por uma questão de conveniência) e -nsignifica saída nada até ou a menos que seja solicitado explicitamente.O pmodificador imprime o resultado.

Você pode fazer uma pesquisa global com o gmodificador como:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

para que você obtenha uma string separada por ' '(poderia ser \n, \tou o que você tem) que você pode processar facilmente.

Ambos são válidos desde que seus valores precedidos pelo caractere da equação abranjam até o final de uma linha e não sejam seguidos por comentários ou outros caracteres com semântica que se desvie de um "valor" simples.


Editar:

Ainda não posso comentar aqui nas postagens de outras pessoas. Para indicar a linha, basta passar o número da linha, no seu caso 3, antes sou antes do caractere de cotação inicial (como no vim).

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

Por favor, dê uma olhada info sed. Por exemplo, 3.2 e 4.7 são de particular interesse para você.

Nicholas
fonte
4

Você pode usar o comando recortar, definindo o delímetro como '=' e, em seguida, imprimir o segundo campo como este:

cut -d'=' -f2
anselal
fonte
3

Várias maneiras de fazer isso, considerando que seu arquivo é chamado foobar:

Especifique o padrão para procurar:

PAT=POP3_SERVER_NAME

Extrair usando sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

Ou usando sedecut

sed -n "/$PAT/p" foobar | cut -d' ' -f3
unxnut
fonte
2

A beleza do Linux / Unix é que geralmente há mais de uma maneira de realizar alguma coisa. No caso da operação, há pelo menos quatro maneiras diferentes de extrair o nome do servidor POP do arquivo:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
thdoan
fonte