我需要将很多.txt
文件粘贴在一起。我使用这个命令:
cat *.txt > newfile.txt
我注意到其中一些文件是空的。如何在脚本中插入控件以防止cat
对这些空文件起作用?
谢谢。
答案1
并不是真的必要,但如果您需要排除空文件:
for i in *.txt; do [ "$i" != newfile.txt ] && [ -s "$i" ] && cat -- "$i"; done >newfile.txt
-s
如果给定文件存在且不为空,则测试为 true(这是标准测试;请参阅)man test
。我们还避免处理输出文件本身。
答案2
在 中zsh
,您可以使用L+0
glob 限定符:
(cat -- *.txt(n-.L+0)) > newfile.txt
(这里,也限制为常规的仅文件 ( .
) 在符号链接解析 ( ) 之后确定(以及大小)-
,并按数字方式对文件列表进行排序 ( n
)file10.txt
如下后 file9.txt
例如)。
通常,包含空文件不会产生任何影响,因为cat
空文件不会产生任何输出。然而,有两件事使它成为一个好主意:
- 您不希望
newfile.txt
自身包含在要传递到的文件列表中cat
。cat
如果输入文件与 stdout 所在的位置相同,某些实现会抱怨。如果不这样做,您最终可能会填满磁盘,就像cat
循环读取输出文件一样。这里,在执行重定向后,glob 被扩展。该重定向会截断输出文件,因此在展开 glob 时它的大小将为 0。 - 通过从传递给 的参数列表中删除不必要的文件
cat
,我们使命令行更短,因此我们不太可能达到其大小限制。不过在这里,您也可以通过使用zsh
's来解决该问题zargs
。
没有zsh
,但如果您有 GNU 实用程序,您可以执行以下操作:
LC_ALL=C find -L . -maxdepth 1 -name '*.txt' ! -name '.*' \
! -name newfile.txt -type f -size +0 -print0 |
sort -V0 |
xargs -r0 cat > newfile.txt
在这里,我们不能依赖,就好像当前目录-size +0
中有很多文件一样,xargs
最终可能会在获取检查(也在此处,并且同时运行,因此重定向可能在启动时尚未执行并检查其大小是否事先存在)。cat
find
newfile.txt
xargs > newfile.txt
find
find
newfile.txt
我们还需要手动排除隐藏文件,因为find
默认情况下不会这样做。我们还需要LC_ALL=C
解决 GNUfind
的非字符问题。在这种情况下,xargs
将解决命令行大小的限制。
该方法的等效项zsh
是:
-L
⟷-
-type f
⟷.
-size +0
⟷L+0
sort -V
⟷n
答案3
与在经典 UNIX 文件系统中一样,读取空文件的开销与检测文件为空的开销几乎相同,因此单独处理空文件没有什么意义,尤其是在cat
-ing 时。
您也没有说明文件是否必须按顺序排列。如果不是(也许 find 甚至保留了此处的顺序),这可能比https://unix.stackexchange.com/a/633734/320598:
(find *.txt \! -size 0 | xargs cat) >newfile.txt