複数のディレクトリを作成してファイルで埋める方法

複数のディレクトリを作成してファイルで埋める方法

いくつかのディレクトリツリーを作成し、ツリーの各端にランダムな内容を含むテキストファイルを埋めたいです。

これまでに試したことは次のとおりです。

#!/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

あなたが間違っていることがうまくいかないのは、リダイレクトとファイル名の生成がxargsではなくシェルによって処理されるためです。

書くとき

foo > foo.out

その後、シェルがfoo実行され、標準出力をキャプチャしますfoo.out

走れば

foo | xargs bar > bar.out

その後、シェルがfoo自動的に実行され、標準出力をキャプチャしてxargs標準出力fooxargs。ある時点で実行され、標準入力として受け取ったデータは引数として渡され、結果のxargs標準出力がの標準出力と区別されないbarように実行されます。シェルはこの標準出力をキャプチャして記録します。barxargsbar.out

あなたの引数は./parent_{0..9}/child_{0..9}/test.txtシェルでも解釈されます。パラメータを削除してパターンで生成されたファイル名に置き換えることで、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バイトの任意のデータを読み取り、それをコマンドライン引数に変換してからそのxargsデータを出力しようとするという意味です(バイナリデータであり、ここではコマンドについて話しているのでうまく進まないでしょう)。

最後に、シェルはそれを見て、>>同じパターンが続く追加されたリダイレクトとして解釈します。

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

しかし、そうすることはできません。一度に1つのファイルにのみリダイレクトできます。これは「あいまいなリダイレクト」エラーです。

最も簡単な解決策は、ファイルを繰り返すことです。

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

xargsを使用するすべてのソリューションは、コマンドライン引数を標準出力に変換するためにechoを必要とし、xargsを使用して同じ標準出力をコマンドライン引数に戻すことができるので、これは確かに非効率的です。

おすすめ記事