Na verdade, esse problema pode ser mais fácil ed, pois é basicamente um editor de texto com script, em vez de um processador de fluxo. Usando ed, você não precisa salvar todas as linhas do arquivo em uma matriz, por exemplo, pois já está fazendo isso por você.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... que Henvelhecerá todas as linhas que !não são a primeira e a primeira que pé Na $última linha, ele xaltera os espaços de espera e de padrão antes da Hantiga - que obtém as linhas salvas anexadas à última linha - e delimina da saída todas as linhas que !não são as $últimas.
Na $última linha, ele xmuda de espaço novamente, s///substituindo o primeiro \ncaractere de linha de linha - que cuida do extra adicionado na linha 2 - e imprime automaticamente o lote.
RESULTADO:
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sem usar o buffer de retenção:
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... apenas para salvar seu exemplo em um arquivo real ...
sed '1p;$!d;r infile' <infile | sed '3d;$d'
Que redireciona <infilepara os primeiros seds' stdin, que só prints a primeira linha antes deleting de saída de todas as linhas que são !e não o $último. A última linha é autoprinted, mas também é a única linha em que o comando final é executada - que é a read a inteira infilenovamente para stdout. Tudo isso passa pelo |tubo para o segundo, sedque só precisa deliminar de sua saída suas terceira e última linhas de entrada para concluir a reorganização.
Você armazena todas as linhas da amatriz e imprime a matriz na ordem que desejar (1ª linha, última ( NR) e de 2 a penúltima.
Usando uma combinação de cabeça / cauda e sed:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Imprima a primeira linha, a última e, com sed, exclua a primeira e a última.
Somente com o sed, só consegui encontrar este comando. Estou certo de que existem maneiras melhores:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Se for a primeira linha, imprima-a (padrão).
Na segunda linha, coloque-o no buffer de espera ( H) e exclua-o do espaço do padrão ( d). E se for a última linha, imprima-a ( p), obtenha o buffer de espera ( x), exclua a linha vazia ( s/^\n//) e imprima-a ( p).
awk
soluções, você é um grandesed
fã ou talvez tenha escritosed
? ;-)awk
- eu nunca tentei. talvez um dia ...Um método ingênuo usando o awk:
Você armazena todas as linhas da
a
matriz e imprime a matriz na ordem que desejar (1ª linha, última (NR
) e de 2 a penúltima.Usando uma combinação de cabeça / cauda e sed:
Imprima a primeira linha, a última e, com sed, exclua a primeira e a última.
Somente com o sed, só consegui encontrar este comando. Estou certo de que existem maneiras melhores:
Se for a primeira linha, imprima-a (padrão).
Na segunda linha, coloque-o no buffer de espera (
H
) e exclua-o do espaço do padrão (d
). E se for a última linha, imprima-a (p
), obtenha o buffer de espera (x
), exclua a linha vazia (s/^\n//
) e imprima-a (p
).fonte
sed
peça seria algo parecidohead -n -1 f | tail -n +2
.-1
sintaxe, poishead
não é portátil.Com perl:
Com awk:
RESULTADO
fonte