입력 디렉터리를 반복적으로 탐색하고 각 파일에 대해 별도의 디렉터리 계층 구조 아래에 해당 파일을 생성하는 스크립트를 작성하고 싶습니다.
예를 들어, 파일은 가 됩니다 . input/a/b/c.txt
이렇게 하면 입력 디렉터리의 이름을 출력 디렉터리의 이름으로 바꾸는 깔끔한 방법은 무엇입니까?output/a/b/c.txt
input/a/d.txt
output/a/d.txt
내가 아는 어느 쪽도 옳다고 생각하지 않습니다. 첫 번째는 #
매개변수 확장을 사용하여 파일 접두어를 제거하는 것입니다. 그러나 입력 디렉터리 이름에 특수 문자가 포함된 경우(예: *
입력 디렉터리 이름이 변수에 있는 경우)도 읽기 어렵습니다.
find input -type f | while read -r infile; do
outfile=output/"${infile#input/}"
mkdir -p "$(dirname "$outfile")"
some-program "$infile" > "$outfile"
done
내가 시도한 또 다른 방법은 입력 디렉터리로 이동하여 모든 항목에 절대 링크를 사용하는 것이었습니다. 그러나 이를 위해서는 여러 번의 호출이 필요 cd
하며 또한 의존적이므로 readlink
이식성이 가장 좋지 않습니다.
abspwd=$(pwd)
absinput=$(readlink -f input)
absoutput=$(readlink -f output)
cd "$absinput"
find . -type f | while read infile; do
outfile="$absoutput/$infile"
mkdir -p "$(dirname "$outfile")"
some-program "$infile" > "$outfile"
done
cd "$abspwd"
다른 방법이 있나요? 이 작업을 수행하는 더 쉬운 방법이 있어야 할 것 같습니다.
답변1
거의 다 왔습니다.
출력에 입력된 디렉토리 구조를 복사하는 rsync를 배치하겠습니다. 그런 다음 찾기 파이프라인이 실행되면 일부 프로그램의 출력이 올바른 위치에 표시됩니다.
TOP="input"
rsync -a -f'+ */' -f'- *' "$TOP"/ output/
find "$TOP" -type f | while IFS= read -r infile; do
outfile=output/${infile#"$TOP"/}
some-program "$infile" > "$outfile"
done
줄 바꿈이 포함된 파일 이름은 올바르게 처리되지 않습니다. 그러한 경우가 필요하다고 생각되면 더 많은 코드를 사용하여 처리할 수 있습니다. 한 디렉터리에서 다른 디렉터리로 파일 이름을 마이그레이션하는 데 주의를 분산시키고 싶지 않습니다.