Existe alguma maneira de dizer sed
para produzir apenas grupos capturados? Por exemplo, dada a entrada:
This is a sample 123 text and some 987 numbers
e padrão:
/([\d]+)/
Eu poderia obter apenas saída 123 e 987 da maneira formatada por referências anteriores?
sed
ativar expressões regulares estendidas com o-E
sinalizador.Respostas:
A chave para fazer isso funcionar é dizer
sed
para excluir o que você não deseja exibir, bem como especificar o que você deseja.Isto diz:
-n
)p
)Em geral, em
sed
você captura grupos usando parênteses e gera o que captura usando uma referência anterior:irá produzir "bar". Se você usar
-r
(-E
para OS X) para regex estendido, não precisará escapar dos parênteses:Pode haver até 9 grupos de captura e suas referências anteriores. As referências anteriores são numeradas na ordem em que os grupos aparecem, mas podem ser usadas em qualquer ordem e podem ser repetidas:
gera "uma barra a".
Se você possui o GNU
grep
(também pode funcionar no BSD, incluindo o OS X):ou variações como:
A
-P
opção habilita expressões regulares compatíveis com Perl. Vejaman 3 pcrepattern
ouman 3 pcresyntax
.fonte
sed
exemplo, se usa a-r
opção (ou-E
para OS X, IIRC), não precisa escapar dos parênteses. A diferença é que entre expressões regulares básicas e expressões regulares estendidas (-r
).O Sed tem até nove padrões lembrados, mas você precisa usar parênteses escapados para lembrar partes da expressão regular.
Veja aqui exemplos e mais detalhes
fonte
sed -e 's/version=\(.+\)/\1/' input.txt
este ainda irá saída o todo input.txt\+
vez de+
. E eu não entendo por que as pessoas usam-e
apenas um comando sed.sed -e -n 's/version=\(.+\)/\1/p' input.txt
see: mikeplate.com/2012/05/09/…sed -E
usar as chamadas expressões regulares "modernas" ou "estendidas" que parecem muito mais próximas aos tipos Perl / Java / JavaScript / Go / qualquer que seja. (Compare comgrep -E
ouegrep
.) A sintaxe padrão possui essas regras de escape estranhas e é considerada "obsoleta". Para mais informações sobre as diferenças entre os dois, executeman 7 re_format
.você pode usar grep
fonte
o
- é por isso que a opção existe - unixhelp.ed.ac.uk/CGI/man-cgi?grep : -o, --only-matching Mostra apenas a parte de uma linha correspondente que corresponde ao PATTERNgrep -Eow -e "[0-9]+" -e "[abc]{2,3}"
Não sei como você pode exigir que essas duas expressões estejam em uma linha, exceto a canalização de um grep anterior (que ainda não funcionaria se um dos padrões corresponder mais de uma vez em uma linha )número (s) de dígitos
Esta resposta funciona com qualquer contagem de grupos de dígitos. Exemplo:
Resposta expandida.
Sim. substitua todo o texto pelo grupo de captura:
Ou com sintaxe estendida (menos aspas anteriores e permite o uso de +):
Para evitar imprimir o texto original quando não houver número, use:
E para combinar vários números (e também imprimi-los):
Isso funciona para qualquer contagem de execuções de dígitos:
O que é muito semelhante ao comando grep:
Sobre \ d
O Sed não reconhece a sintaxe '\ d' (atalho). O equivalente ascii usado acima
[0-9]
não é exatamente equivalente. A única solução alternativa é usar uma classe de caracteres: '[[: digit:]] `.A resposta selecionada usa essas "classes de caracteres" para criar uma solução:
Essa solução funciona apenas para (exatamente) duas execuções de dígitos.
Obviamente, como a resposta está sendo executada dentro do shell, podemos definir algumas variáveis para tornar essa resposta mais curta:
Mas, como já foi explicado, usar um
s/…/…/gp
comando é melhor:Isso abrangerá repetidas execuções de dígitos e gravará um comando curto (er).
fonte
Eu acredito que o padrão dado na pergunta foi apenas a título de exemplo, e o objetivo era corresponder a qualquer padrão.
Se você tiver um sed com a extensão GNU permitindo a inserção de uma nova linha no espaço do padrão, uma sugestão é:
Estes exemplos estão com o tcsh (sim, eu sei que é o shell errado) com o CYGWIN. (Editar: para o bash, remova o conjunto e os espaços ao redor =.)
fonte
+
, você precisaria escapar dele ou usar a-r
opção (-E
para OS X). Você também pode usar\{1,\}
(ou-r
ou-E
sem o escape).Desista e use Perl
Como
sed
não o corta, vamos jogar a toalha e usar o Perl, pelo menos é LSB, enquanto asgrep
extensões GNU não são :-)Imprima a peça correspondente inteira, sem grupos correspondentes ou olhando para trás:
Resultado:
Correspondência única por linha, geralmente campos de dados estruturados:
Resultado:
Com lookbehind:
Vários campos:
Resultado:
Várias correspondências por linha, geralmente dados não estruturados:
Resultado:
Com lookbehind:
Resultado:
fonte
Experimentar
Compreendi isso no cygwin:
fonte
Não é o que o OP solicitou (capturando grupos), mas você pode extrair os números usando:
Fornece o seguinte:
fonte