Sed

如何將多個文件的倒數第二行列印到一個文件中?

  • October 20, 2015

我在一個目錄中有許多不同長度的 CSV 文件。我想將每個文件的倒數第二行放入一個文件中。我嘗試了類似的東西tail -2 * | head -1 > file.txt,然後意識到為什麼這不起作用。

我正在使用 BusyBox v1.19.4。

編輯:我確實看到了與其他一些問題的相似之處,但這是不同的,因為它是關於讀取多個文件的。湯姆亨特的答案中的for循環是我需要並且以前沒有想到的。

for i in *; do tail -2 "$i" | head -1; done >>file.txt

那應該sh(因此 Busybox)兼容,但我沒有可用於測試 ATM 的非 bash。

根據有用的評論進行編輯。

使用 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

…但是您需要確保每個 infile 中至少有兩行,因為在這種情況下sed不會-s分離任何流,並且一次性會影響輸出的其餘部分。但tail絕對不會列印每個文件中最後兩行,並且它會在每組之後有一個空行,並以其規範的文件名標題引導每組*(如果有可能會導致問題)實際上是文件名中的換行符)*。

這是tail列印的:

tail -n2 file[15]0*

==> file10 <==
9
10

==> file100 <==
99
100

==> file1000 <==
999
1000

==> file50 <==
49
50

…如果您沒有更好的選擇,那麼處理流並不是那麼難。

想一想,如果文件中行少於兩行,則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]...

同樣令人沮喪的是,(我更喜歡它,並且正式包含在 android 系統中)錯誤地報告它確實支持其輸出中的選項,然後拒絕在其他地方辨識它:toybox sed --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

該死。

引用自:https://unix.stackexchange.com/questions/237252