A seguir, imprimirá a linha correspondente TERMINATE
até o final do arquivo:
sed -n -e '/TERMINATE/,$p'
Explicado: -n
desativa o comportamento padrão sed
de imprimir cada linha depois de executar seu script, -e
indicar um script para sed
, /TERMINATE/,$
é uma seleção de intervalo de endereço (linha), o que significa que a primeira linha corresponde à TERMINATE
expressão regular (como grep) no final do arquivo ( $
) , e p
é o comando de impressão que imprime a linha atual.
Isso será impresso a partir da linha que segue a linha correspondente TERMINATE
até o final do arquivo:
(de APÓS a linha correspondente a EOF, NÃO incluindo a linha correspondente)
sed -e '1,/TERMINATE/d'
Explicado: 1,/TERMINATE/
é uma seleção de faixa de endereço (linha) que significa a primeira linha da entrada da 1ª linha correspondente à TERMINATE
expressão regular e d
é o comando delete que exclui a linha atual e pula para a próxima linha. Como sed
o comportamento padrão é imprimir as linhas, ele imprimirá as linhas após TERMINATE
o final da entrada.
Editar:
Se você deseja as linhas antes TERMINATE
:
sed -e '/TERMINATE/,$d'
E se você deseja as duas linhas antes e depois TERMINATE
em 2 arquivos diferentes em uma única passagem:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Os arquivos antes e depois conterão a linha com terminação, para processar cada um que você precisa usar:
head -n -1 before
tail -n +2 after
Edit2:
Se você não desejar codificar os nomes de arquivos no script sed, poderá:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Mas então você precisa escapar do $
significado da última linha para que o shell não tente expandir a $w
variável (observe que agora usamos aspas duplas ao redor do script em vez de aspas simples).
Esqueci de dizer que a nova linha é importante após os nomes dos arquivos no script, para que o sed saiba que os nomes dos arquivos terminam.
Edição: 2016-0530
Sébastien Clément perguntou: "Como você substituiria o código fixo TERMINATE
por uma variável?"
Você faria uma variável para o texto correspondente e, em seguida, faria da mesma maneira que no exemplo anterior:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
para usar uma variável para o texto correspondente com os exemplos anteriores:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Os pontos importantes sobre a substituição de texto por variáveis nesses casos são:
- Variáveis (
$variablename
) incluídas em single quotes
[ '
] não serão "expandidas", mas variáveis dentro de double quotes
[ "
] serão. Portanto, você deve alterar todos os single quotes
para double quotes
se eles contiverem texto que você deseja substituir por uma variável.
- As
sed
faixas também conter um $
e são imediatamente seguidos por uma letra como: $p
, $d
, $w
. Eles também irá olhar como variáveis a serem expandidas, então você tem que escapar esses $
caracteres com uma barra invertida [ \
] como: \$p
, \$d
, \$w
.
grep 'TERMINATE' file