ディレクトリにはさまざまな長さのCSVファイルがたくさんあります。各ファイルの最後の行から2行目をファイルに入れたいです。私は似たようなことを試しtail -2 * | head -1 > file.txt
てから、なぜこれがうまくいかないのか気づきました。
私はBusyBox v1.19.4を使用しています。
編集:他の質問と似ていますが、複数のファイルを読むという点で異なります。 Tom Hunterの答えのループfor
は私が必要だったが、以前は考えなかったことです。
答え1
for i in *; do tail -2 "$i" | head -1; done >>file.txt
これはBusyboxと互換性がなければなりませんsh
が、テストするための非bash ATMはありません。
役に立つコメントに基づいて編集されました。
答え2
GNUまたはBSDの使用sed
:
sed -s 'x;$!d' -- files... >outfile
...例えば:
for i in 10 50 100 1000
do seq "$i" >file"$i"
done
sed -s 'x;$!d' -- file[15]0*
9
99
999
49
以下を使用してこれを行うこともできtail
ます。
tail -n2 file[15]0* | sed -ne'n;p;n;n'
9
99
999
49
...しかし、あなたは必要です確かにこの場合、ストリームは分離さsed
れず、1回限り-s
は残りの出力に影響を与えるため、各内部ファイルには少なくとも2行が必要です。しかし、tail
何も印刷されません。もっと各ファイルの最後の 2 行よりも各グループの後に空行があり、各グループは標準ファイル名ヘッダーで始まります。(実際にファイル名に改行があると問題が発生する可能性があります。)。
tail
印刷された内容は次のとおりです。
tail -n2 file[15]0*
==> file10 <==
9
10
==> file100 <==
99
100
==> file1000 <==
999
1000
==> file50 <==
49
50
...より良いオプションがなければ、ストリームを処理することはそれほど難しくありません。
そして、もしあればそれについて考えてみてください。はいファイルに 2 行未満がある場合、sed
ソリューションはファイルの空行を出力します。ファイルに何も書き込まないようにするには、次のようにします。
sed -s 'x;$!d;1d' -- file[15]0*
...そしてそれはすべてです。
このコマンドは組み込みコマンドtail | sed
でのみ機能しますが、残念ながら機能します。busybox
busybox sed
いいえ分割ストリームオプションを処理します-s
。少なくとも私のビルドは次のことを行いません。
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]...
恥ずかしいことは同じだ。toybox sed
(私はそれを好み、正式にAndroidに含まれています)誤って報告したことする出力はオプションをサポートし、--help
他の場所ではそれを認識しません。
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
くそー。