xargs의 인수를 사용하여 다른 표현식을 평가하는 방법은 무엇입니까?

xargs의 인수를 사용하여 다른 표현식을 평가하는 방법은 무엇입니까?

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)평가됩니다(문자열 생성 ). 이것이 바로 코드가 파일을 올바른 이름으로 복사하지 않는 이유입니다.fxargs

"해당 파일 또는 디렉터리가 없습니다"라는 오류는 발견된 파일의 경로 이름으로 대체되었기 f때문에 발생합니다 .DIR_OUT/copied_ffind


동일한 작업을 수행하는 보다 강력한 방법

find . -type f -name '*.txt' -exec sh -c '
    for pathname do
        cp "$pathname" "DIR_OUT/copied_${pathname##*/}"
    done' sh {} +

또는 찾은 경로 이름을 및 사이에 null로 끝나는 문자열로 전달하도록 xargs주의하세요 .findxargs

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 ffind가 파일 결과만 제공하는지 확인 -print0make find는 null 종료 출력을 인쇄합니다. 하나의 결과만 프로세스에 전달되도록 -n1합니다. 결과가 없으면 작업을 실행하지 않도록 지시합니다. make find는 null 종료 입력을 허용합니다.xargs-rxargs-0xargs

run 명령은 인라인 스크립트와 빈 인수가 있는 셸입니다( -c인수가 스크립트에 전달되는 방식이기 때문입니다).

xargs인수를 에 전달하면 sh -c 'commands' ''첫 번째 인수가 $1-c 내에 있게 됩니다. 작은따옴표는 쉘 처리 호출을 방지 $()하고 $1.

관련 정보