如何将多个文件的倒数第二行打印到一个文件中?

asw*_*ine 1 sed awk tail busybox head

我在一个目录中有许多 CSV 文件,它们的长度各不相同。我想将每个文件的倒数第二行放入一个文件中。我尝试了类似的东西tail -2 * | head -1 > file.txt,然后意识到为什么这不起作用。

我正在使用 BusyBox v1.19.4。

编辑:我确实看到了与其他一些问题的相似性,但这是不同的,因为它是关于读取多个文件。for汤姆亨特答案中的循环是我需要的,而且以前没有想到。

Tom*_*unt 8

for i in *; do tail -2 "$i" | head -1; done >>file.txt
Run Code Online (Sandbox Code Playgroud)

这应该是sh(因此 Busybox)兼容,但我没有可用于测试 ATM 的非 bash。

根据有用的评论进行编辑。


mik*_*erv 5

使用 GNU 或 BSD sed

sed -s 'x;$!d' -- files... >outfile
Run Code Online (Sandbox Code Playgroud)

...例如:

for   i in        10 50 100 1000
do    seq "$i"   >file"$i"
done
sed -s 'x;$!d' -- file[15]0*
Run Code Online (Sandbox Code Playgroud)
sed -s 'x;$!d' -- files... >outfile
Run Code Online (Sandbox Code Playgroud)

你也可以这样做tail

tail -n2 file[15]0* | sed -ne'n;p;n;n'
Run Code Online (Sandbox Code Playgroud)
for   i in        10 50 100 1000
do    seq "$i"   >file"$i"
done
sed -s 'x;$!d' -- file[15]0*
Run Code Online (Sandbox Code Playgroud)

...但您需要确保每个 infile 中至少有两行,因为在这种情况下sed不会-s分离任何流,一次性会影响输出的其余部分。但tail绝对不会打印任何更多的不是在每个文件的最后两行,它会按照每组那些有一个空行,带领各组其只具备文件名头(这可能会造成问题,如果有实际上是文件名中的换行符)

这是tail打印出来的:

tail -n2 file[15]0*
Run Code Online (Sandbox Code Playgroud)
9
99
999
49
Run Code Online (Sandbox Code Playgroud)

...如果您没有更好的选择,那么处理流并不是那么难。

并思考它,如果在一个文件小于两行,sed解决方案将输出该文件的空行。如果您希望它为该文件根本不写任何内容:

sed -s 'x;$!d;1d' -- file[15]0*
Run Code Online (Sandbox Code Playgroud)

...会做的伎俩。


tail | sed命令仅适用于busybox内置函数,但不幸的是,busybox sed处理-s单独的流选项。至少,我的构建没有:

busybox sed --help
Run Code Online (Sandbox Code Playgroud)
tail -n2 file[15]0* | sed -ne'n;p;n;n'
Run Code Online (Sandbox Code Playgroud)

同样令人沮丧的是,(我更喜欢它,并且它正式包含在 android 系统中)错误地报告它确实支持其输出中的选项,然后拒绝在其他地方识别它:toybox sed --help

toybox sed -s -e 'x;$!d' -- file[15]0*
Run Code Online (Sandbox Code Playgroud)
9
99
999
49
Run Code Online (Sandbox Code Playgroud)

该死的。