grep todas as linhas em um arquivo e escrever linha em um arquivo do ponto de correspondência de padrão

1

Por exemplo, um arquivo temp.txt contém informações como abaixo:

adsf on line jhkjhvjdbvjvbvbdjkvn  
qerwtt on line fdgdgdgdd  
qwqertg on line safffasffaf  
wrt on line adaddsd

Eu quero grep para on line em todas as linhas do arquivo e gravar a parte restante das linhas em outro arquivo, ou seja, após o processo no arquivo temp.txt , o novo arquivo deve conter:

on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd  

Como posso fazer isso no terminal linux?

    
por Navaneeth Cp 25.01.2016 / 07:19

5 respostas

7

Use a opção -o de grep para selecionar apenas a parte desejada, no seu caso use o padrão on line .* para selecionar a parte começando de on line até o final da (s) linha (s):

% grep -o 'on line .*' temp.txt >new.txt

% cat new.txt 
on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd
    
por 25.01.2016 / 07:23
3

Dada a tag vi nesta questão, e o fato de que eu descobri que a edição automatizada de arquivos com Comandos ex compatíveis com POSIX recebem pouca atenção neste site em comparação com a infinidade de conselhos sobre sed , awk , grep e até Perl, aqui está uma ex compatível com POSIX comando que irá realizar a filtragem desejada:

ex -sc 'g/.*\(on line\)/s/// | .w!>>output
q!' input

Observe a nova linha embutida no comando - isso é necessário para a portabilidade completa do POSIX, já que não há outra maneira definida de terminar o comando g lobal; no entanto, as implementações mais permitem vários comandos -c , caso em que o seguinte liner funcionaria da mesma forma:

ex -sc 'g/.*\(on line\)/s/// | .w!>>output' -c 'q!' input

Há um pouco de magia regex e muito ex -command magic contido neste comando, e como ex não parece ser amplamente conhecido, explicarei cada parte:

-s inicia ex no modo silencioso, "em preparação para processamento em lote", portanto, nada é enviado para o terminal.

-c significa "Execute o seguinte comando quando o arquivo for aberto." ( input é o nome do arquivo a ser aberto).

O comando ex em si é realmente dois comandos:

g/.*\(on line\)/s/// | .w!>>output
q!

g é o comando "global" e significa "Execute os seguintes comandos (o resto da linha) em todas as linhas do arquivo que correspondem à regex especificada."

O regex dado é .*\(on line\) , que significa 'Qualquer caractere qualquer número de vezes, incluindo 0, seguido de' on line ''. Os parênteses são usados para capturar "on line" para backreferencing mais tarde.

Na verdade, o comando g poderia ser igual a g/on line/ e funcionaria da mesma forma. No entanto, o comando s ubstitute que escrevi usa nada para sua regex - s// - que significa "reutilizar a última expressão regular usada". Em seguida, o comando s usa para o texto de substituição, o que significa "on line", neste caso.

O símbolo de pipe | em um comando ex não significa um pipe como no shell. Em vez disso, é normalmente usado para delimitar comandos ex separados, cada um para ser executado sequencialmente, mas de forma independente. No entanto, o comando g lobal é uma exceção a isso: em um comando global, a barra vertical separa os comandos que estão dentro do comando global - isto é, esses comandos são executados somente as linhas que correspondem ao regex especificado no comando global.

O comando após a barra vertical é, neste caso, um comando w rite. É precedido por um ponto . especificando "linha atual"; sem esse especificador de endereço, o comando write gravará o arquivo inteiro , independentemente da linha atual. (Como estamos usando o comando write dentro de um comando global, se omitirmos o ponto, o comando write gravaria todo o arquivo depois que cada linha correspondente tiver o comando de substituição executado nele!)

O >> significa "Se o arquivo já existir, anexe-o em vez de dar um erro." Como estamos gravando no arquivo várias vezes, isso é necessário, caso contrário, acabaríamos com a linha last que foi gravada no arquivo de saída. O ! anterior ao >> significa "Se o arquivo não já existir, crie o arquivo e grave nele em vez de gerar um erro." (Sem o ! não é especificado no POSIX se isso aconteceria ou não.) E é claro que output é o nome do arquivo para gravar.

Por fim, é claro, q! significa "sair sem salvar as alterações no arquivo atual". Fizemos substituições em muitas linhas do arquivo input , mas não queremos salvar essas alterações, então usamos q! .

Existem algumas outras abordagens que são equivalentes, por exemplo, as seguintes:

ex -sc '%s/.*\(on line\)//e | v//d
w output | q!' input

Mas isso usa o e flag para o comando substitute, que não está no POSIX. (Se esse sinalizador for omitido, o processamento em lote será interrompido na ocasião em que o regex .*\(on line\) não for encontrado em nenhum lugar do arquivo.)

Claro, onde ex realmente brilha está na edição de arquivos no local . Mas certamente pode ser usado para filtrar um arquivo para outro arquivo, conforme ilustrado acima.

    
por 25.01.2016 / 09:48
2

Tente isto:

grep -o 'on line .*' temp.txt > out.txt

O parâmetro -o faz com que o grep mostre apenas a parte correspondente da linha, que é o que você deseja.

    
por 25.01.2016 / 07:24
0

Se o seu grep não suportar a opção -o :

sed 's/^.*\(on line\)//' temp.text > out.txt

Ou se você quiser apenas as linhas que contêm on line :

sed -n 's/^.*\(on line\)//p' temp.text > out.txt

Observe que, se houver várias ocorrências de on line , ele imprimirá a parte da linha que começa com a ocorrência mais à direita dela. Para a ocorrência mais à esquerda:

sed '/on line/!d;s//\
&/;s/.*\n//' temp.text > out.txt
    
por 25.01.2016 / 08:24
0

curl remotamente ou localmente neste exemplo, imprime localmente .txt

se os dados, conforme indicado na pergunta, forem: linha por linha e não incluírem a cadeia 'on line' na primeira coluna de dados.

curl file:///home/$USER/Public/input.txt | grep -o 'on line .*' > output.txt

ou

curl https://yoursite.com/Public/input.txt | grep -o 'on line .*' > output.txt

isto irá escrever sobre o seu atual output.txt e não estará ciente de uma pasta somente leitura

    
por 28.07.2018 / 13:21