在 shell 中输出到一系列文件的最简单解决方案

在 shell 中输出到一系列文件的最简单解决方案

我可以创建一系列文件,例如:

touch file{A..Z}.txt 

那么将输出引导到这个范围的最简单的解决方案是什么?

例如:echo 'hello, world'到 . 范围内的所有文件{A..Z}

答案1

如果您使用此命令创建文件:

touch file{A..Z}.txt

您同样可以使用相同的扩展向它们写入相同的文本(并创建它们):

echo hello, world | tee file{A..Z}.txt

tee命令还将写入标准输出,因此您也会收到一份写入您终端的副本。/dev/null如果您不需要,请将其重定向到:

echo hello, world | tee file{A..Z}.txt >/dev/null

跑步man tee在您的本地系统上获取有关该命令的信息。例如,该-a标志会将文本附加到文件集。

bash在很多情况下,扩展本身是由 shell 执行的。看man bash了解详情。

答案2

zsh

echo new test > file{A..Z}.txt

这是假设该multios选项尚未被禁用。

实际上,当 fd 被重定向多次以进行写入(使用>, >>, 1<>, >!,>|重定向运算符,但这也适用于|...)时zshzsh将其重定向到管道,并且在管道的另一端,有一个后台 zsh以类似方式将数据发送到所有目标的过程tee

如果该noclobber选项打开,并且fileK.txt例如已经存在,则重定向将中止,并且命令不会在打开它时运行,因此fileK.txt不会被破坏,但fileA.txtfileJ.txt被打开(并以 0 大小创建)。

请注意,所有这些文件都是同时打开的,因此,与 一样tee,如果重定向到太多文件,您将遇到打开文件描述符数量的限制:

$ echo test > file{A..Z}{A..Z}{A..Z}.txt
zsh: multio failed for fd 3: too many open files
$ echo test | tee file{A..Z}{A..Z}{A..Z}.txt
tee: fileBNH.txt: Too many open files
tee: fileBNI.txt: Too many open files
tee: fileBNJ.txt: Too many open files
[...]
tee: fileZZZ.txt: Too many open files
test

在这里,使用这样的命令echo几乎不需要任何运行成本(无论如何都比创建管道和通过它们推送数据的开销要少,类似tee行为所需要的),您可以串行打开、填充和关闭文件,而不是并行,直接写入echo文件:

for f (file{A..Z}.txt) echo new test > $f

答案3

如果您已经创建了文件并且只想附加新文本,则可以使用带有 -a 选项的 tee 命令:

echo "new text" | tee -a file{A..Z}.txt

要将文件(例如 file0)的内容添加到您的文件中:

<file0 tee -a file{A..Z}.txt

相关内容