Unix:合并多个文件,同时删除所有文件的第一行

34

我有100多个文件需要合并,但是每个文件的第一行必须被删除。在Unix下,最有效的方法是什么?我猜想可能是使用catsed '1d'命令。所有文件都具有相同的扩展名,并且位于同一个文件夹中,因此我们可以使用*.extension命令指向这些文件。非常感谢!


6
要删除第一行,请参阅例如tail(tail -n +2 file). - Some programmer dude
1
@Someprogrammerdude 应该使用 tail -q -n +2 file,以避免输出包含文件名的头部。 - Rodrigo
5个回答

38

假设你的文件名按照你想要添加文件的顺序排序,你可以使用:

ls *.extension | xargs -n 1 tail -n +2

编辑:在Sorin和Gilles提出的有关管道ls输出可能存在危险的评论之后,您可以使用以下方法:

find . -name "*.extension" | xargs -n 1 tail -n +2

-1 用管道将ls的输出传递给其他命令是不合适的,ls并不是为此而设计的,请使用find命令。 - Sorin
在什么情况下这会是不好的,Sorin? - Abdel
你能给一个可能出现的管道ls输出问题的链接吗?谢谢。 - xpapad
上面的参考文献将解析“ls”的输出与像“for x in *.txt”这样的内部字符串操作进行了比较。它没有将解析“ls”的输出与解析“find”的输出进行比较。根据同样的逻辑,两者都是“不好的”。 - Kaz
参考文献确实提到了 find,但它建议使用GNU的 find 扩展来输出空终止字符串。用普通的 find 替换 ls 是完全没有意义的。 - Kaz
如果我执行以下命令:find . -name "*.csv" | xargs -n 1 tail -n +2 > output.extension,那么我的 output.csv 文件会被包含在 find . -name "*.csv" 中,结果输出文件会读取自身并再次输出到自身。除了将输出文件更改为非 .csv 文件之外,有没有其他避免这种情况的方法? - YellowPillow

20

每个人都喜欢把事情弄复杂,但实际上这很简单:

tail -q -n +2 file1 file2 file3

等等。如果你有大量的文件,你可以先将它们加载到数组中:

list=(file1 file2 file3)
tail -q -n +2 "${list[@]}"

如何在当前目录下找到指定扩展名的所有文件?

list=(*.extension)
tail -q -n +2 "${list[@]}"
或者只是简单地
tail -q -n +2 *.extension

我尝试了tail -n +2 *.extension。我使用的tail版本返回了tail: Can only process one file at a time.,这就解释了为什么答案更加复杂。 - zr00

6
只需删除第一行后,将每个文件追加即可。
#!/bin/bash

DEST=/tmp/out
FILES=space separated list of files

echo "" >$DEST
for FILE in $FILES
do
    sed -e'1d' $FILE >>$DEST
done

3

tail 命令可以输出文件的最后几行。你可以指定要打印的行数,或者从哪一行开始省略(使用 -n +N,其中 N 是要打印的第一行的编号,从 1 开始计数,所以 +2 将省略一行)。如果使用 GNU 工具(例如在 Linux 或 Cygwin 下),FreeBSD 或其他有 -q 选项的系统:

tail -q -n +2 *.extension

tail 命令在每个文件之前打印一个标题,-q 选项不是标准的。如果你使用的实现没有这个选项,或者想要可移植性,你需要逐个迭代文件。

for x in *.extension; do tail -n +2 <"$x"; done

另外,您可以调用Awk,它有一种方法来识别每个文件的第一行。如果您有许多小文件,则这可能会更快,如果您有许多大文件,则可能会更慢。

awk 'FNR != 1' *.extension

2
ls -1 file*.txt | xargs nawk 'FNR!=1'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接