Existe um comando que me permita editar as últimas n linhas em um arquivo? Eu tenho vários arquivos, todos com um número diferente de linhas dentro. Mas eu gostaria de modificar as últimas n linhas em cada arquivo. O objetivo é substituir vírgulas por ponto e vírgula nas últimas n linhas. Mas apenas nas últimas n linhas.
Não quero excluir nenhuma linha, só quero substituir cada vírgula por um ponto-e-vírgula nas últimas n linhas em cada arquivo.
Usando o comando sed, sou capaz de substituir a última linha por este comando. Conforme descrito aqui: Como remover texto na última linha de um arquivo?
Mas isso só me permite modificar a última linha, e não o último n número de linhas.
text-processing
awk
sed
sku2003
fonte
fonte
sed '24,$s/,/:/g' filename
onde24
é o line` começandoRespostas:
Para substituir vírgulas por ponto e vírgula nas últimas n linhas por
ed
:Dividindo isso:
ed -s
= executado silenciosamente (não relate os bytes escritos no final)'$-'
= do final do arquivo ($
) menos ...$((n-1))
= n-1 linhas ...$' ... '
= cite o restante do comando para protegê-lo do shell),$s/,/;/g
= ... até o final do arquivo (,$
), pesquise e substitua todas as vírgulas por ponto e vírgula.\nwq
= finalize o comando anterior e salve e saiaPara substituir vírgulas por ponto e vírgula nas últimas n linhas por
sed
:Desmembrando isso:
-i
= editar o arquivo "no local"$(( ... ))
= faça algumas contas:$( wc -l < input)
= obtém o número de linhas no arquivo-n + 1
= retrocede n-1 linhas,\$
= de n-1 linhas até o final do arquivo:s/,/;/g
= substitua as vírgulas por ponto e vírgula.fonte
wc -l < input
porwc -l input
. Deve ser mais rápido por alguns nanossegundos :)wc -l input
gera o nome do arquivo também; nós só queremos a contagem de linhaSolução usando tac e sed para substituir cada vírgula por ponto e vírgula nas últimas 50 linhas de file.txt:
fonte
Com o GNU
head
e um shell semelhante ao Bourne:Estamos substituindo o arquivo por si próprio. Isso é OK aqui para uma transliteração byte-to-byte, mas que não necessariamente se a modificação implica a alteração do tamanho do arquivo (nesse caso, você gostaria de substituir
1<> file
com> other-file && mv other-file file
, por exemplo).fonte
1<>
quais eu não estava familiarizado. Além disso, asponge
partir do moreutils é uma boa ferramenta para pipelines nos quais você deseja substituir sua entrada.Vamos supor que queremos substituir as últimas
7
linhas da seguinte sequência pelo shell script e pela implementação GNU desed
:Etapa 1 : permite obter o número da última linha da sequência, como a seguir. Dê uma olhada nisso e naquilo :
Etapa 2 : vamos definir o número de linhas (no final da sequência) que pretendemos editar:
Etapa 3 : vamos calcular a linha de partida com base nas variáveis anteriores, como a seguir. Dê uma olhada nisso :
Etapa 4 : agora, podemos substituir as últimas 7 linhas de sequência por outra coisa, como a seguir. Dê uma olhada nisso :
A etapa 4 está usando a seção 4.4 da página do manual sed, que diz:
Etapa 4, também está usando aspas duplas, conforme mencionado aqui .
Bem, as 4 etapas são desnecessárias se usarmos a resposta de Gohu assim:
fonte
Use
tail
e cante para sed:tail -n 20 file | sed 's/,/;/g'
Isso funciona no arquivo nas últimas 20 linhas. Se você deseja que você mude diretamente para o arquivo, use:
tail -n 20 file | sed -i 's/,/;/g'
fonte