시간이 지나면서 나는 같은 패턴을 반복해서 겪었습니다. 일종의 디렉터리 구조가 있었습니다.
example/
├── a
│ └── c
│ ├── d.txt (120k)
│ └── e.txt (60k)
└── b
└── f.txt (280k)
example_grepped
예를 들어 각 파일에 명령을 적용하여 파일을 다른 디렉터리에 "복사"하고 싶습니다. cp
예를 들어 grep ERROR
, 구조는 동일하지만 파일이 grep
.
example_grepped/
├── a
│ └── c
│ ├── d.txt (1k)
│ └── e.txt (0b)
└── b
└── f.txt (12k)
미디어 파일(FLAC에서 MP3로, PNG에서 JPG로)을 변환하는 것과 동일한 패턴입니다. 이번에는 빌드 프로세스 중에 다양한 아키텍처 형식을 변환합니다.
사용할 수 있는 일반 명령이 있나요? foobar example example_grepped --command 'grep ERROR'
또는 와 유사합니까 foobar flacs mp3s --command 'ffmpeg -i {} {}.mp3'
?
어쩌면 겸손한 xargs
깃발일까요? ( find
파이프xargs
거의충분하지만 대부분의 명령은 디렉터리 구조가 이미 존재할 것으로 예상합니다. )
답변1
디렉토리 구조를 별도로 다시 만들지 않고도 내가 찾을 수 있는 가장 가까운 대답은 다음을 사용하는 것입니다.설치하다:
cd example
find . -type f -exec sh -c 'grep ERROR {} | install -D /dev/stdin /tmp/example_grepped/{}' \;
불행하게도 위의 방법은 명령이 결과를 STDOUT으로 보낼 수 있는 경우에만 작동합니다.
답변2
이 문제를 해결하는 또 다른 방법은 어쨌든 재귀적으로 복사하는 프로그램을 사용하는 것입니다. 확인했지만 rsync
잠깐 살펴본 후에도 콜백 옵션을 찾을 수 없습니다. 하지만 gnu에는 파일의 입력을 받는 명령을 제공할 수 있는 tar
옵션이 있습니다 . 그런데 파일을 어떻게 생성합니까? 음, 라는 명령은 에서 현재 파일 이름을 찾습니다 .--to-command
stdin
$TAR_FILENAME
모든 것을 종합하면 기본 호출은 다음과 같습니다.
tar cf - example | tar xf - --to-command="./script example_grepped 'grep-pattern'"
스크립트의 모양은 다음과 같습니다.
#!/bin/bash
mkdir -p $(dirname "$1/$TAR_FILENAME")
grep '$2' >"$1/$TAR_FILENAME"
exit 0
이 문제를 해결하는 또 다른 방법은 명령줄에서 명령이 실행되도록 하는 스크립트에 tar 파이프를 래핑하는 것입니다. 그러나 이 구조를 탈출하는 mkdir ...dirname
것은 약간 어려울 것입니다.
답변3
#!/bin/bash
filter() {
local target_root="${@: -1}"
target_path=$(sed -E "s/[^/]*/$target_root/" <<< "$1")
target_dir=$(dirname "$target_path")
mkdir -p "$target_dir"
if [[ -f $1 ]]; then
# do your grep thing here
grep burger "$1" > "$target_path"
fi
}
export -f filter
source_root="example"
target_root="example_grepped"
find "$source_root/" -print0 | xargs -0 -I content bash -c "filter 'content' '$target_root'"
이 스크립트는 공백이 포함된 디렉터리 및 파일 이름에도 작동합니다.
소스 디렉터리("examples")가 있는 곳에서 이 스크립트를 실행하세요.
답변4
GNU Parallel을 사용하면 다음과 같은 작업을 수행할 수 있습니다.
cd src
find . -type f | parallel 'mkdir -p ../dst/{//}; dostuff --input {} --output ../dst/{}'