여러 디렉터리를 만들고 파일로 채우는 방법

여러 디렉터리를 만들고 파일로 채우는 방법

일부 디렉토리 트리를 만들고 트리의 각 끝에 임의의 내용이 포함된 텍스트 파일을 채우고 싶습니다.

지금까지 시도한 내용은 다음과 같습니다.

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

하지만 그렇게 할 수는 없습니다. 한 번에 하나의 파일로만 리디렉션할 수 있습니다. 이는 "모호한 리디렉션" 오류입니다.

가장 간단한 해결책은 파일을 반복하는 것입니다.

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

xargs를 사용하는 모든 솔루션에는 명령줄 인수를 표준 출력으로 변환하기 위해 echo가 필요하고 xargs를 사용하여 동일한 표준 출력을 다시 명령줄 인수로 다시 변환할 수 있으므로 이는 확실히 비효율적입니다.

관련 정보