我有多个文件,想要使用 cat
命令将它们拼接起来。
假设这些文件是:
File1.txt
foo
File2.txt
bar
File3.txt
qux
我想要拼接文件,最终的文件应该像这样:
foo
bar
qux
不要使用常规的cat File*.txt > finalfile.txt
,而是考虑使用:
foo
bar
qux
如何正确地做到这一点?
你可以这样做:
for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done
在运行上述命令之前,请确保文件finalfile.txt
不存在。
如果您被允许使用awk
,可以执行以下操作:
awk 'FNR==1{print ""}1' *.txt > finalfile.txt
AWK '{print $0}' *.txt
- timgerawk 'FNR==1 && NR > 1 ...'
来避免这个问题。 - tripleeedone
之后加上 >finalfile.txt
,则可以覆盖写入而不是追加写入,这将消除需要在循环之前确保文件不存在或为空的要求。 - tripleeeawk '1' *.txt
:smile: - hustnzj如果您的文件数量足够少,可以将每个文件列出来并在Bash中使用进程替换,在每对文件之间插入一个换行符:
cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt
… | xargs -I{} kubectl -n alex exec {} -- cat blah.log <(echo) >> blahblah.logs
cat: /dev/fd/63: 没有那个文件或目录,命令以退出码 1 终止。 - tuxErrante<(echo)
是在本地运行的。也许可以尝试使用 -- bash -c "cat blah.log <(echo)"
? - Robert Tupelo-Schnecksh -c“echo -e'\ n \ n'| cat - /.. /logs/a.log"
。 - tuxErrante如果是我在做的话,我会使用sed:
sed -e '$s/$/\n/' -s *.txt > finalfile.txt
这个sed模式中“$”有两个含义,第一,“$”仅匹配最后一行号(作为一个应用模式的行范围),第二,它在替换模式中匹配行结尾。
如果你的sed版本没有“-s”选项(分别处理输入文件),你可以使用循环来完成所有操作:
for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt
sed -s '$G' *.txt > finalfile.txt
,将所有.txt
文件的末尾添加一个空白行,并将结果保存到finalfile.txt
中。 - Ruud Heldermanfind
中使用了 *.txt
的位置而崩溃了我的电脑,这意味着该文件被追加到了自己上面! - xeruf这在Bash中有效:
for f in *.txt; do cat $f; echo; done
与使用 >>
(追加)的答案不同,此命令的输出可以被导入其他程序。
示例:
for f in File*.txt; do cat $f; echo; done > finalfile.txt
(for ... done) > finalfile.txt
(括号是可选的)for ... done | less
(导入 less)for ... done | head -n -1
(这将去除尾随的空行)如果你喜欢的话,可以使用xargs
来完成它,但主要思想仍然是相同的:
find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt
xargs
比循环要容易得多。 - RawwrBag这就是我在 OsX 10.10.3 上刚刚完成的方式。
for f in *.txt; do (cat $f; echo '') >> fullData.txt; done
由于简单的“echo”命令没有参数,因此不会插入新行。
grep
命令并带上参数 -h
来避免输出文件名。grep -h "" File*.txt
将提供:
foo
bar
qux
,
可以抑制添加一个额外的尾随空行):print '\n'.join(open(f).read() for f in filenames),
这是一个丑陋的Python单行程序,在shell中调用并将输出打印到文件中:
python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
nl=`mktemp`
printf '\n' > $nl
cat file1 $nl file2 $nl file3
rm $nl
一个更高级的版本可能是这样的。
nl=`mktemp`
printf '\n' > $nl
find file1 file2 file3 -print0 |
xargs -0 printf "%s\0$nl\0" |
tr '\0' '\n' |
sed -n '$!p;$q' |
tr '\n' '\0' |
xargs -0 cat
rm $nl