
Eu tenho um arquivo prova.txt
como este:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
extra1
extra2
bla
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
extra2
bla
bla
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
e preciso sair de "Comece a pegar aqui" até a primeira linha em branco. A saída deve ser assim:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Como você pode ver, as linhas após "Comece a pegar aqui" são aleatórias, então o sinalizador -A -B grep não funciona:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
Você pode me ajudar a encontrar uma maneira de capturar a primeira linha que será capturada (como "Comece a capturar a partir daqui"), até uma linha em branco. Não posso prever quantas linhas aleatórias terei depois de "Começar a pegar a partir daqui".
Qualquer solução compatível com Unix é apreciada (grep, sed, awk é melhor que perl ou similar).
EDITADO: após resposta brilhante de @ john1024, gostaria de saber se é possível:
1° classifique o bloco (de acordo com Comece a pegar a partir daqui: 1, depois 1, depois 2)
2° remova 4 linhas (em ordem alfabética aleatória) fix1,fix2,fix3,fix4 mas são sempre 4
3° eventualmente remover idiotas aleatórios, como o comando sort -u
O resultado final deve ser assim:
# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4
#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
ou
# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
A segunda saída é melhor que a primeira. Alguma outra mágica de comando unix é necessária.
Responder1
Usando o awk
Tentar:
$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4
Start to grab from here: 2
random1546
random2561
Start to grab from here: 3
random45
random22131
/Start to grab/,/^$/
define um intervalo. Começa com qualquer linha que corresponda Start to grab
e termina com a primeira linha vazia, ^$
, a seguir.
Usando sed
Com uma lógica muito semelhante:
$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4
Start to grab from here: 2
random1546
random2561
Start to grab from here: 3
random45
random22131
-n
diz ao sed para não imprimir nada, a menos que solicitemos explicitamente. /Start to grab/,/^$/p
diz para imprimir quaisquer linhas no intervalo definido por /Start to grab/,/^$/
.
Responder2
Estou postando uma solução alternativa, pois pode ser útil para casos de uso de algumas pessoas. Esta solução não atende exatamente aos requisitos declarados, para a melhor solução consulte a resposta de @ John1024.
Você pode usar o awk com o separador de registros definido como uma string vazia, o awk irá interpretá-los como novas linhas em branco:
$ awk '/Start/' RS= prova.txt
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Esta versão não preserva as novas linhas em branco na saída. Também mostrará o contexto antes da partida, se presente. Este comportamento pode ser muito útil ao procurar algo em um arquivo e você deseja ver o bloco delimitado por nova linha do qual ele faz parte, por exemplo:
$ awk '/random1546/' RS= prova.txt
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Por exemplo, acho isso útil ao procurar coisas em ini
arquivos.