如何创建多个目录并用文件填充它们

如何创建多个目录并用文件填充它们

我想制作一些目录树,并用带有随机内容的文本文件填充树的每一端。

这是我到目前为止所尝试的:

#!/bin/bash

set -e

echo "Generating test folders"

mkdir -p ./parent_{0..9}/child_{0..9}
head -c 100 /dev/urandom | xargs echo >> ./parent_{0..9}/child_{0..9}/test.txt

echo "done"

执行时,我收到此错误:

./gen-test.sh: line 8: ./parent_{0..9}/child_{0..9}/test.txt: ambiguous redirect

我做错了什么以及什么是完成这项任务的更明智的方法?

答案1

您做错的事情不起作用的原因是因为重定向和文件名生成是由 shell 处理的,而不是由 xargs 处理的。

当你写的时候

foo > foo.out

然后 shellfoo将为您运行,捕获其标准输出,并将其写入foo.out.

如果你跑

foo | xargs bar > bar.out

然后 shellfoo将为您运行,捕获其标准输出,运行xargs并将标准输出发送foo到 的标准输入中xargs。在某些时候,xargs将运行,并将其在标准输入上收到的数据作为参数传递给它,并且它将以导致 的标准输出与 的标准输出无法区分的bar方式执行此操作。 shell 将捕获该标准输出,并将其写入.barxargsbar.out

您的参数./parent_{0..9}/child_{0..9}/test.txt也由 shell 解释。它删除该参数,并将其替换为该模式生成的文件名,以便mkdir命令行变得类似于(...为了简洁而添加):

mkdir -p ./parent_0/child_0/test.txt ./parent_0/child_1/test.txt ./parent_0/child_2/test.txt ... ./parent_1/child_0/test.txt ... ./parent_9/child_9/test.txt

后来你跑

head -c 100 /dev/urandom | xargs # ...

echo这意味着您读取 100 字节的随机数据,将其转换为by 的命令行参数xargs,然后它将尝试输出该数据(这不太可能顺利,因为它是二进制数据,而且我们正在讨论这里是命令行)。

最后,shell 看到>>,将其解释为附加重定向,后跟相同的模式;这意味着重定向变成

>> /parent_0/child_0/test.txt /parent_0/child_1/test.txt # and so on

但你不能那样做;您一次只能重定向到一个文件(这是您看到的“不明确的重定向”错误)。

最简单的解决方法是循环遍历文件:

for file in /pattern_0/child_0/test.txt; do
    head -c 100 /dev/urandom > $file
done

因为任何使用 xargs 的解决方案都需要 echo 将命令行参数转换为标准输出,而只能使用 xargs 将相同的标准输出再次转换回命令行参数,这显然是低效的。

相关内容