将 xargs 输出从多个文件保存到一个文件

将 xargs 输出从多个文件保存到一个文件

我有这三个文本文件:

#1.txt
hey stackoverflow
#2.txt   
hey stackexchange
#3.txt
hello world

我使用此命令列出我的目录中的最后 3 个文件,然后列出cat它们,然后将 3 个文件的所有输出保存到一个文件 ( all.txt)

命令 :

ls -alth *txt | head -3 | xargs -n1 cat

我如何将输出重定向到文件?

答案1

使用-l(对于长列表)选项ls在这里没有意义,因为您只需要文件名(与-h(用于报告大小的 GNU 扩展相同)人类格式)随之而来)。

使用 的xargs默认分割方式ls也是不正确的,因为这会破坏包含空格、换行符、引号、反斜杠的文件名...

使用该-a选项也是毫无意义的,因为 shell 是通过扩展此处的 glob 来计算文件列表的*txt,而不是ls,并且默认情况下 glob 扩展不包括隐藏文件。

你想要(在最近的 GNU 系统和 GNU shell (bash) 上):

shopt -s extglob
ls -Ltd --zero -- !(all.)txt | head -zn3 | xargs -r0 cat -- > all.txt

dotglob如果您希望考虑隐藏文件,还可以设置该选项)。

添加:

  • 选项-L,以便ls对于符号链接类型的文件,考虑符号链接目标的修改时间
  • -d因为如果其中一些文件的类型为目录,您不想ls列出它们的内容。
  • --zero//处理以 NUL 分隔的记录,NUL 是唯一不能出现在文件路径中的字符-z-0
  • !(all.)txt而不是*txt确保all.txt不包含在列表中,这可能会导致无限循环填满磁盘。
  • -r选项以xargs避免cat在未找到文件时运行。
  • --标记选项的结尾,因此以或开头的文件名-不会被视为选项。lscat

或者在任何系统上使用 zsh 而不是 bash:

set -o extendedglob
cat -- (^all.)txt(-.om[1,3]) > all.txt

在哪里:

  • ^xzsh 与 ksh 等效!(x)(bash 通过其选项支持 ksh 扩展 glob 运算符的子集extglob
  • -相当于-L
  • .限制于常规的文件(或常规文件的符号链接),不包括目录、fifo、设备...
  • om相当于-t按修改时间排序。
  • [1,3]比如head -zn3对前 3 个的限制。
  • 如果 glob 与任何文件都不匹配,则不会运行该命令并返回错误(与上面的 bash 命令相反,all.txt不会创建/截断)。

如果您希望考虑隐藏文件,请添加D 全局限定符( cat -- (^all.)txt(D-.om[1,3]) > all.txt)

相关内容