Eu tenho este arquivo:
sometext1{
string1
}
sometext2{
string2
string3
}
sometext3{
string4
string5
string6
}
Desejo procurar neste arquivo uma sequência específica e imprimir tudo antes dessa sequência até a abertura {
e tudo depois dessa sequência até o fechamento }
. Eu tentei conseguir isso com o sed, mas se eu tentar imprimir tudo no intervalo, /{/,/string2/
por exemplo, sed imprime isso:
sometext1{
string1
}
sometext2{
string2
sometext3{
string4
string5
string6
}
Se eu procurar a string "string2", preciso que a saída seja:
sometext2{
string2
string3
}
Obrigado.
text-processing
sed
rodrigo
fonte
fonte
grep -n '' <infile | sed ...
. Ossed
comandos precisarão ser modificados; especificamente os bits de/
endereço/
que procuram por^
âncoras top de linha. Então, se você estava usando a minha resposta você provavelmente poderia fazer:grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'
. Todas as linhas de saída serão prefixadas com os números de linha do arquivo original, seguidos por dois pontos1:sometext1{\n2:string1
e assim por diante.sed
filtrará apenas o que filtraria antes, exceto que cada linha de saída é aberta com um número.Respostas:
Aqui estão dois comandos. Se você deseja um comando que apare até a última
.*{$
linha em uma sequência (como @don_crissti faz comed
), você pode:... que funciona anexando todas as linhas ao
H
espaço antigo, seguindo um\n
caractere ewline, substituindo oh
espaço antigo por todas as linhas correspondentes{$
e trocandoh
espaços antigos e padrão por cada linha correspondente^}
- e, assim, liberando seu buffer.Ele só imprime linhas que correspondem a
{
uma linha de\n
ew e,PATTERN
em seguida, em algum momento - e isso só acontece imediatamente após uma troca de buffer.Ele elimina todas as linhas de uma série de
{$
correspondências até a última da sequência, mas você pode obter todas as inclusivas, como:O que ele faz é trocar o padrão e
h
os espaços antigos para cada...{$.*^}.*
sequência, anexa todas as linhas da sequência aoH
espaço antigo após um\n
caractere de linha de linha eD
elimina o primeiro\n
caractere de linha de ew que ocorre no espaço de padrão para cada ciclo de linha antes de começar novamente com o que resta.Obviamente, a única vez em que ele recebe
\n
ewline no espaço do padrão é quando uma linha de entrada corresponde^}
- o final do seu intervalo - e, portanto, quando ele executa o script novamente em qualquer outra ocasião, ele apenas puxa a próxima linha de entrada normalmente.Porém, quando
PATTERN
é encontrado no mesmo espaço de padrão que uma linha de\n
ew, imprime o lote antes de substituí-lo^}
novamente (para que possa terminar o intervalo e liberar o buffer) .Dado este arquivo de entrada (obrigado don) :
As primeiras impressões:
...e o segundo...
fonte
}
. Isso pode ser benéfico para ...open{\nsub;\n{ command; }\n}; close
- mas não tenho certeza de que é o que está acontecendo aqui ... #{...}
blocos? Se for esse o caso e você estiver usando a primeira solução, poderá fazê-lo/{$/,/^}/H
no início, em vez de apenasH
. Mas se você também tentou a segunda solução e ainda encontrou o mesmo erro, provavelmente não ajudará, porque essa já faz isso. E também não desconteed
. don tem uma resposta muito boa aqui eed
pode ser aplicada para usar arquivos temporários de buffer com muita simplicidade, o que deve impedir a saturação do buffer de memória.Aqui está uma solução com
ed
:isso é:
Isso pressupõe que há apenas uma linha
PATTERN
entre cada par de,{
}
caso contrário, você obterá uma saída duplicada para cada linha adicionalPATTERN
dentro do mesmo bloco.Ele funcionará para múltiplos que
{
}
contêm uma única linha correspondente,PATTERN
por exemplo, para um arquivo de testePATTERN
em duas seções diferentes:corrida
saídas:
fonte
Com
pcregrep
:Ou com o GNU,
grep
desde que a entrada não contenha NUL bytes:fonte
Onde:
string4
-> string a ser correspondidat1.txt
-> contém o conteúdo do arquivo mencionado na consultafonte
nome do arquivo sed -n '/ string / p'
o -n quando adicionado ao sed suprimiu o comportamento padrão do sed, esta declaração pode não fornecer exatamente o que você deseja, mas deve apenas deslocar a string
fonte