![xargs의 인수를 사용하여 다른 표현식을 평가하는 방법은 무엇입니까?](https://linux55.com/image/147996/xargs%EC%9D%98%20%EC%9D%B8%EC%88%98%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EB%8B%A4%EB%A5%B8%20%ED%91%9C%ED%98%84%EC%8B%9D%EC%9D%84%20%ED%8F%89%EA%B0%80%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
basename
인수가 주어진 표현식을 평가하고 싶습니다 xargs
.
내가 테스트한 내용은 다음과 같습니다.
find . -name '*.txt' | xargs -I f cp f DIR_OUT/copied_$(basename f)
제대로 평가되지 않았기 no file or directory
때문 이다 .$(basename f)
파일 이름을 복사하고 변경하는 두 단계로 나눌 수 있지만 xargs
.
답변1
명령에서 사용하는 명령 대체는 명령이 시작되기 전에 한 번만 $(basename f)
평가됩니다(문자열 생성 ). 이것이 바로 코드가 파일을 올바른 이름으로 복사하지 않는 이유입니다.f
xargs
"해당 파일 또는 디렉터리가 없습니다"라는 오류는 발견된 파일의 경로 이름으로 대체되었기 f
때문에 발생합니다 .DIR_OUT/copied_f
find
동일한 작업을 수행하는 보다 강력한 방법
find . -type f -name '*.txt' -exec sh -c '
for pathname do
cp "$pathname" "DIR_OUT/copied_${pathname##*/}"
done' sh {} +
또는 찾은 경로 이름을 및 사이에 null로 끝나는 문자열로 전달하도록 xargs
주의하세요 .find
xargs
find . -type f -name '*.txt' -print0 |
xargs -0 sh -c '
for pathname do
cp "$pathname" "DIR_OUT/copied_${pathname##*/}"
done' sh
두 변형 모두에서 주어진 경로 이름을 반복하고 이를 디렉토리 아래의 새 이름에 복사하는 작은 인라인 쉘 스크립트를 호출합니다 DIR_OUT
. ${pathname##*/}
로 대체될 수 있습니다 $( basename "$pathname" )
.
-print0
(in find
)과 -0
(in ) 은 xargs
비표준이지만 일반적으로 구현됩니다.
관련된:
답변2
원래 명령을 약간 수정해야 합니다.
find . -name '*.txt' | xargs -I f sh -c 'cp f DIR_OUT/copied_$(basename f)'
답변3
설명하려면 $()
쉘에서 실행해야 합니다 xargs
.
바라보다여기
또한 파일 이름에 문제가 있는 문자가 나타나는 것을 방지하려면 시스템에서 허용하는 경우 find의 null로 구분된 출력을 사용해야 합니다.
이렇게 하면 원하는 작업이 수행됩니다. (어딘가에 null 지원이 없으면 -0
에서 제거 xargs
하고 -print0
로 바꾸세요 -print
.)
find . -type f -name '*.txt' -print0 | xargs -n1 -r0 /bin/sh -c 'cp "$1" "DIR_OUT/copied_$(basename "$1")"' ''
-type f
find가 파일 결과만 제공하는지 확인
-print0
make find는 null 종료 출력을 인쇄합니다. 하나의 결과만 프로세스에 전달되도록
-n1
합니다. 결과가 없으면 작업을 실행하지 않도록 지시합니다. make find는 null 종료 입력을 허용합니다.xargs
-r
xargs
-0
xargs
run 명령은 인라인 스크립트와 빈 인수가 있는 셸입니다( -c
인수가 스크립트에 전달되는 방식이기 때문입니다).
xargs
인수를 에 전달하면 sh -c 'commands' ''
첫 번째 인수가 $1
-c 내에 있게 됩니다. 작은따옴표는 쉘 처리 호출을 방지 $()
하고 $1
.