不是一个命令,而是一个简单的单行:
for f in *.txt; do cat -- "$f"; printf "\n"; done > newfile.txt
Run Code Online (Sandbox Code Playgroud)
这将给出此错误:
cat: newfile.txt: input file is output file
Run Code Online (Sandbox Code Playgroud)
但是你可以忽略它,至少在 GNU/Linux 系统上是这样。Stéphane Chazelas 在评论中指出,显然,在其他系统上,这可能会导致无限循环,因此要避免它,请尝试:
for f in *.txt; do
[[ "$f" = newfile.txt ]] || { cat -- "$f"; printf "\n"; }
done > newfile.txt
Run Code Online (Sandbox Code Playgroud)
或者只是不要.txt
向输出文件添加扩展名(它不需要并且根本没有任何区别,无论如何),这样它就不会包含在循环中:
for f in *.txt; do cat -- "$f"; printf "\n"; done > newfile
Run Code Online (Sandbox Code Playgroud)
使用 GNU sed
:
sed -s -e $'$a\\\n' ./*.txt >concat.out
Run Code Online (Sandbox Code Playgroud)
这将连接所有数据,concat.out
同时在处理的每个文件的末尾附加一个空行。
-s
GNU的选项sed
使$
地址匹配每个文件的最后一行,而不是像往常一样,所有数据的最后一行。该a
命令在给定位置附加一行或多行,添加的数据为换行符。换行符被编码为$'\n'
,即作为“C 字符串”,这意味着我们正在使用理解这些的外壳(如bash
或zsh
)。否则必须将其添加为文字换行符:
sed -s -e '$a\
' ./*.txt >concat.out
Run Code Online (Sandbox Code Playgroud)
实际上,'$a\\'
并且'$a\ '
似乎也有效,但我不完全确定为什么。
这也有效,如果有人认为a
命令太麻烦而无法正确执行:
sed -s -e '${p;g;}' ./*.txt >concat.out
Run Code Online (Sandbox Code Playgroud)
这些变体中的任何一个也会在最后一个文件的输出末尾插入一个空行。如果不需要最后的换行符,请sed '$d'
在重定向到输出文件之前通过传递整体结果来删除它:
sed -s -e '${p;g;}' ./*.txt | sed -e '$d' >concat.out
Run Code Online (Sandbox Code Playgroud)
使用 GNU awk
:
gawk -v RS='^$' -v ORS= '{
print sep $0; sep="\n";
}' ./file*.txt >single.file
Run Code Online (Sandbox Code Playgroud)
文件名中的前缀点斜杠./
用于避免命名的文件出现问题,file=x.txt
例如,当awk
这些字符串出现在代码后面时,将这些字符串读取为变量;awk
另一种 GNUawk
方法是:
gawk 'BEGINFILE{if (ARGIND>1) print ""};1' ./file*.txt >single.txt
Run Code Online (Sandbox Code Playgroud)
这是更好的,因为即使最后一行不以换行符结尾,它也会添加一个空行,并且可以避免将整个文件加载到内存中。
还有一种sed
替代方法,但要删除最后一条\n
ewline,您应该添加另一个管道sed ... |
来删除它。
sed -s '$s/$/\n/' file*.txt >single.file
Run Code Online (Sandbox Code Playgroud)
zsh
有一个P
glob 限定符来为每个文件名加上任意参数的 glob 前缀。
虽然它通常用于为cmd *.txt(P[-i])
每个文件名添加给定选项的前缀,但您可以使用此处在每个文件之前插入任何给定文件。可以使用 完成包含空行的临时文件=(print)
,因此您可以执行以下操作:
() { cat file*.txt(P[$1]); } =(print)
Run Code Online (Sandbox Code Playgroud)
在 Linux 或 Cygwin 上,您还可以执行以下操作:
cat file*.txt(P[/dev/stdin]) <<< ''
Run Code Online (Sandbox Code Playgroud)
也许不完全是您想要的,但就像评论中建议的 Quas\xc3\xadmodo 一样,tail
除了带有文件名的标头之外,GNU 还可以添加空行:
$ echo 'this is foo' > foo.txt \n$ echo 'this is bar' > bar.txt \n$ tail -n+1 foo.txt bar.txt \n==> foo.txt <==\nthis is foo\n\n==> bar.txt <==\nthis is bar\n
Run Code Online (Sandbox Code Playgroud)\n导致-n+1
它打印整个文件;它的意思是“从第一行开始打印尾部”。
如果您希望即使只有一个文件也添加标头以保持一致性,您可以使用-v
.
$ tail -n+1 foo.txt \nthis is foo\n$ tail -v -n+1 foo.txt \n==> foo.txt <==\nthis is foo\n
Run Code Online (Sandbox Code Playgroud)\n