grep
pode fazer isso com a opção -o
:
grep -o 'Foo=[^,]*' file
Estou procurando uma maneira fácil de cortar pares de valores-chave (em que a chave é única e especificada) do texto, da mesma forma como cut
pode ser usado para cortar uma coluna especificada em um arquivo CSV. As chaves que estou procurando nem sempre estão na mesma posição relativa na linha - isto é, usar cut
seguido por sed
não vai funcionar, porque a chave que estou procurando nem sempre é na mesma coluna ,
-delimited.
O texto em questão é, de fato, CSV, mas acontece que os valores são pares chave / valor, delimitados por =
.
Por exemplo, posso analisar um arquivo com as três linhas a seguir:
Foo=1, Bar=2, Baz=3
Bar=4, Foo=2, Baz=3
Bar=42, Baz=42, Foo=3
Eu gostaria de cortar este texto para gerar o par chave / valor para uma chave específica. Se eu estivesse procurando Foo
, minha saída desejada seria:
Foo=1
Foo=2
Foo=3
O ideal é que eu queira uma ferramenta de linha de comando com sintaxe semelhante a cut
e possa ler a partir de stdin e de um arquivo.
Existe tal ferramenta?
A solução awk
para arredondar a lista de alternativas:
awk -v RS=', ' -F'=' '$1=="Foo"' <file>
Trate cada registro a ser delimitado por ', '
e divida cada registro em campos no caractere =
(usando -F
) também. Então é só uma questão de correspondência no primeiro campo $1
. A sugestão mostrada aqui é uma correspondência de string simples, sinta-se à vontade para usar regexes, por exemplo $1~/\<Foo\>/
.
Dependendo da complexidade da sua situação do mundo real, esse comando sed
pode ser suficiente:
sed -n 's/^.*\(\<Foo=[^,]*\).*//p'
Aqui está o exemplo trabalhado
FIELD='Foo'
sed -n "s/^.*\(\<${FIELD}=[^,]*\).*//p' << xxEOFxx
Foo=1, Bar=2, Baz=3
Bar=4, Foo=2, Baz=3
Bar=42, Baz=42, Foo=3
xxEOFxx
Foo=1
Foo=2
Foo=3
Dado seu exemplo, uma solução frágil poderia envolver cut
:
tr ', ' '[\n*]' <input | cut -sd F -f1-
... o qual colocaria cada par de chave / valor em uma linha separada por tr
, formando as vírgulas e espaços intervenientes em \n
ewlines e, em seguida, cut
linhas que não contêm F
. Mas esse é um exemplo altamente especializado e só pode funcionar se você puder ter certeza de que um F
ocorre apenas nos pares de chave / valor desejados.
Caso contrário, sed
seria o que eu usaria:
sed 'y/ ,/\n\n/;/^Foo=/P;D' <input
Que também tr
apresentará vírgulas e espaços de intervenção em \n
ewlines, mas somente P
rint os pares de chave / valor que começam com a string Foo=
. Contanto que os espaços sejam separadores confiáveis, os itens acima funcionariam para portavelmente imprimir os pares% chave / valor Foo
em uma linha separada, não importando quantas vezes eles pudessem ocorrer em uma linha de entrada, e imprimissem mais nada - mesmo para linhas que não contêm a chave / valores que você deseja imprimir.
Se você não tiver um grep
disponível com a opção -o
, isso também funcionará:
sed -e 's/, /\n/g' | grep '^Foo='
Isso está usando sed
para substituir cada vírgula + espaço por uma nova linha (dividindo cada par de valores-chave em sua própria linha) e, em seguida, grep para procurar apenas a chave "Foo".
Caso de teste:
printf "%s\n" "Foo=1, Bar=2, Baz=3" "Bar=4, Foo=2, Baz=3" "Bar=42, Baz=42, Foo=3" \
| sed -e 's/, /\n/g' | grep '^Foo='
Tags text-processing scripting