pcregrep -io1 'something="(\w+)"' myfile.txt
( -i
para correspondência insensível a maiúsculas, -o1
para imprimir o primeiro grupo de captura).
O GNU grep
suporta um -P
(se construído com suporte a regex compatível com perl) e -o
. No entanto, seu -o
está limitado à impressão de todas as partes correspondentes. Você pode, no entanto, usar operadores de look-around perl para contornar isso:
grep -iPo '(?<=something=")\w+(?=")' myfile.txt
(isto é, um regexp que coincide com a sequência de caracteres do componente da palavra , desde que siga something="
e seja seguido por "
).
Ou com PCRE recente o suficiente:
grep -iPo 'something="\K\w+(?=")' myfile.txt
(onde \K
redefine o início da string correspondida ).
Mas se você for usar regexps perl, é melhor usar perl
:
perl -C -lne 'print for /something="(\w+)"/ig' myfile.txt
Com GNU ou BSD sed
, para retornar apenas a correspondência mais à direita por linha:
sed -nE 's/.*something="(\w+)".*//pi' myfile.txt
Portável (como suporte de regex estendido e correspondência insensível a maiúsculas e minúsculas são extensões não padrão não suportadas por todas as implementações sed
):
sed -n 's/.*[sS][oO][mM][eE][tT][hH][iI][nN][gG]="\([[:alnum:]_]\{1,\}\)".*//p' myfile.txt
Aquele assume% maiúscula i
é I
. Isso significa que, em locais onde o% bac_de% é i
, por exemplo, o comportamento será diferente da solução anterior.
Uma solução padrão / portátil que pode encontrar todas as ocorrências em uma linha:
awk '{while(match(tolower($0), /something="[[:alnum:]_]+"/)) {
print substr($0, RSTART+11, RLENGTH-12)
$0 = substr($0, RSTART+RLENGTH-1)}}' myfile.txt
Isso pode não funcionar corretamente se a entrada contiver texto cuja versão minúscula não tenha o mesmo tamanho (em número de caracteres).
Pegadinhas:
- Haverá algumas variações entre todas essas soluções em que
İ
(e\w
) corresponde a localidades diferentes da C / POSIX. Em qualquer caso, deve pelo menos incluir sublinhado, todos os algarismos decimais e as letras do alfabeto latino (maiúsculas e minúsculas). Se você quiser apenas isso, corrija a localidade para C. - Como já foi mencionado, a correspondência insensível a maiúsculas e minúsculas é muito dependente do local. Se você se importa apenas com
[[:alnum:]_]
vsa-z
letras inglesas, você pode consertar o local para C novamente. - O operador
A-Z
regexp, com implementações GNU de.
, pelo menos, nunca corresponderá a seqüências de bytes que não fazem parte de um caractere válido. Em uma localidade UTF-8, por exemplo, isso significa que não corresponderá a caracteres de um conjunto de caracteres de um byte com o conjunto de 8 bits. Ou, em outras palavras, para que a soluçãosed
funcione corretamente, o conjunto de caracteres usado no arquivo de entrada deve ser o mesmo que o da localidade do usuário. -
Os utilitários
sed
,perl
e GNU geralmente trabalham com linhas de qualquer tamanho e contêm qualquer valor de byte arbitrário (mas observe a advertência acima) e considerarão os dados extras após o último caractere de nova linha como uma linha extra. Outras implementações desses utilitários podem não. -
Os padrões acima são combinados em cada linha na entrada. Isso significa que eles não podem corresponder a mais de uma linha de entrada. Não é um problema para um padrão como
pcregrep
que não pode abranger mais de uma linha, mas, no caso geral, se você quiser que seu padrão corresponda a um texto que pode abranger várias linhas comosomething="\w+"
, será necessário para:- altera o tipo de registro em que você trabalha.
something=".*?"
,grep --null
(GNUsed -z
apenas),sed
,perl -0
(GNUawk -v RS='
e versões recentes deawk
'mawk
apenas) podem trabalhar em registros delimitados por NUL em vez de linhas (registros delimitados por nova linha ), GNUawk
pode usar qualquer regexp como o separador de registro (com-v RS='regexp'),
perlany byte value (with
-0ooo '). -
pcregrep
tem um modo-M
multiline para isso. - use o modo slurp de
perl
, em que toda a entrada é o único registro (com-0777
)
Em seguida, para perl e pcre, lembre-se de que
.
não corresponderá a caracteres de nova linha, a menos que o sinalizadors
esteja ativado, por exemplo, compcregrep -Mio1 '(?s)something="(.*?)"'
ouperl -C -l -0777 -ne 'print for /something="(.*?)"/gis'
- altera o tipo de registro em que você trabalha.
- Tenha em atenção que algumas versões de
grep
epcregrep
tiveram erros com-z
ou-M
, e os motores regexp em geral podem ter alguns limites incorporados na quantidade de esforço que podem colocar em correspondência com regexp.