for i in *; do tail -2 "$i" | head -1; done >>file.txt
Isso deve ser sh
(e, portanto, o Busybox) compatível, mas eu não tenho um não-bash disponível para testar ATM.
Editado de acordo com comentários úteis.
Eu tenho muitos arquivos CSV em um diretório que tem vários comprimentos. Eu gostaria de colocar o segundo a última linha de cada arquivo em um arquivo. Eu tentei algo como tail -2 * | head -1 > file.txt
, então percebi porque isso não funciona.
Estou usando o BusyBox v1.19.4.
Edit: Eu vejo a semelhança com algumas outras perguntas, mas isso é diferente porque é sobre a leitura de vários arquivos. O loop for
na resposta de Tom Hunt é o que eu precisava e não tinha pensado antes.
Com um GNU ou BSD sed
:
sed -s 'x;$!d' -- files... >outfile
... por exemplo:
for i in 10 50 100 1000
do seq "$i" >file"$i"
done
sed -s 'x;$!d' -- file[15]0*
9
99
999
49
Você também pode fazer isso com tail
:
tail -n2 file[15]0* | sed -ne'n;p;n;n'
9
99
999
49
... mas você precisa ter certeza de que há pelo menos duas linhas em cada arquivo, porque nesse caso sed
não é -s
eparating nenhum fluxo, e um -off afetará o resto da saída. Mas tail
definitivamente não vai imprimir nenhum mais que as duas últimas linhas em cada arquivo, e ele seguirá cada conjunto daqueles com uma linha em branco, e liderará cada conjunto com sua especificação ' d nome do arquivo cabeçalho (o que pode causar problemas se houver novas linhas nos nomes de arquivos, na verdade) .
Isso é o que tail
imprime:
tail -n2 file[15]0*
==> file10 <==
9
10
==> file100 <==
99
100
==> file1000 <==
999
1000
==> file50 <==
49
50
... o que, se você não tem uma opção melhor, não é tão difícil de controlar.
E pensando nisso, se houver menos de duas linhas em um arquivo, a solução sed
emitirá uma linha em branco para esse arquivo. Se você preferir, não escreveu nada para esse arquivo:
sed -s 'x;$!d;1d' -- file[15]0*
... faria o truque.
O comando tail | sed
funciona somente com busybox
builtins, embora, infelizmente, busybox sed
não não manipule a opção -s
eparate streams. Pelo menos, minha compilação não:
busybox sed --help
BusyBox v1.21.1 (2013-07-28 11:02:27 EDT) multi-call binary.
Usage: sed [-inr] [-f FILE]... [-e CMD]... [FILE]...
or: sed [-inr] CMD [FILE]...
Além disso, é frustrante que toybox sed
(o que eu prefiro e que esteja oficialmente incluído nos sistemas android) falsamente reporta que faz apoiar a opção em sua saída --help
, e então se recusa a reconhecê-la em outro lugar:
toybox sed -s -e 'x;$!d' -- file[15]0*
usage: sed [-inrE] [-e SCRIPT]...|SCRIPT [-f SCRIPT_FILE]... [FILE...]
Stream editor. Apply one or more editing SCRIPTs to each line of input
(from FILE or stdin) producing output (by default to stdout).
-e add SCRIPT to list
-f add contents of SCRIPT_FILE to list
-i Edit each file in place.
-n No default output. (Use the p command to output matched lines.)
-r Use extended regular expression syntax.
-E Alias for -r.
-s Treat input files separately (implied by -i)
...
sed: Unknown option s
caramba.