이름에 공백이있는 파일이 들어있는 디렉토리가있는 경우
$ ls -1 dir1
file 1
file 2
file 3
다음과 같이 다른 디렉토리에 모두 복사 할 수 있습니다.
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
그러나 출력 find dir1 -mindepth 1
에는 이스케이프되지 않은 공백이 포함됩니다.
$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3
print0
대신에 사용 print
하면 출력에는 여전히 이스케이프되지 않은 공백이 포함됩니다.
$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3
을 사용하여 이러한 파일을 수동으로 복사하려면 cp
공백을 이스케이프 처리해야합니다. 그러나 내가 명령을 사용하는지 또는 명령의 끝에 있는지에 관계없이 cp
의 주장이 나올 때 이것은 불필요 해 보인다 .find
+
\;
그 이유는 무엇입니까?
답변
find
명령 직접 명령을 실행한다. 파일 이름 인수를 포함한 명령은 셸이나 파일 이름을 수정할 수있는 다른 방법으로 처리되지 않습니다. 매우 안전합니다.
명령 행 {}
에 표시된 파일 이름을 이스케이프 할 필요가없는 것이 맞습니다 find
.
find
원시 파일 이름을 디스크에서 직접 -exec
명령 의 내부 인수 목록으로 전달합니다 (이 경우 cp
명령).
답변
문제는 두 부분으로 구성됩니다.
- 어떻게 않습니다
find
사용하여 전화 프로그램에 관리-exec
파일 이름에 공백이 문제로 실행하지 않고, 및 -print0
옵션 은 무엇 입니까?
첫 번째 find
는 실제로 “exec” 라고하는 관련 호출 그룹 중 하나 인 시스템 호출 입니다. 파일 이름에 대한 정보를 잃지 않고 파일 이름을이 호출에 직접 인수로 전달한 다음 새 프로세스를 작성한 후 직접 전달합니다.
POSIX find
기능 +
은 이론적 근거 로 다음과 같이 설명됩니다 .
SVR4
find
유틸리티 의 기능은-exec
1 차 + 터미네이터였습니다. 이를 통해 특수 문자 (특히 개행 문자)가 포함 된 파일 이름을 파일 이름으로 파이프하는 경우 발생하는 문제없이 그룹화 할 수 있습니다xargs
. 다른 구현에서는이 문제를 해결하기위한 다른 방법, 특히-print0
null 바이트 종결자가있는 파일 이름을 쓴 기본 방법이 추가되었습니다 . 이것은 여기에서 고려되었지만 채택되지는 않았습니다. null 종결자를 사용한다는 것은 find의-print0
출력 을 처리하려는 모든 유틸리티 가 현재 읽고있는 null 종결자를 구문 분석하는 새로운 옵션을 추가해야 한다는 것을 의미했습니다
.
그것은 ” 특히-print0
차”는 GNU를 의미 find
하고 xargs
있는 다른 방법으로 문제를 해결한다. 또한 FreeBSD find
및 에서도 지원됩니다 xargs
. 호출에 -0
옵션 ( 매뉴얼 페이지 참조 )을 추가 한 경우 xargs
해당 프로그램은 “널 바이트”문자로 끝나는 행을 승인합니다. 차례로 exec -functions를 xargs
호출 하여 작업 을 수행 합니다 . 와 피처 와 피처 의 주요 차이점 은 전자가 파이프를 통해 파일 이름을 전달하지만 후자는 그렇지 않습니다. 개발자는 거의 모든 기능에 대한 용도를 찾습니다. 파이프도 예외는 아닙니다.-print0
-0
+
POSIX cp 에는없는 -t
옵션을 사용하는 OP의 예로 돌아갑니다 . 그보다는 GNU cp에서 제공하는 확장 (일명 “비표준 기능”) 입니다. 의 확장은 이 예제를 개선 시키지는 않지만 효과적으로 사용할 수있는 다른 경우가 있습니다 . GNU가 받아 들일 수 있는 이식 가능한 대안이 있다는 것을 명심하십시오 .cp
-0
xargs
+
find
답변
( 이것은 주석이어야하지만 너무 큽니다. )
시도해보고 싶은 사람들을 위해 :
전달 된 위치 매개 변수를 나열하는 스크립트를 작성하고이를 호출하십시오 list_positional_parameters.sh
.
#!/bin/bash
# http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html
# Try globbing patterns, e.g. "X[[:digit:]][[:digit:]]" to see what happens
if [ $# -lt 1 ]; then
echo "Usage: $0 and then at least one parameter"
exit 1
fi
counter=1
while (($#)); do
echo "$counter = '$1'"
# pop positional argument 1 off the stack of positional arguments
shift
(( counter++ ))
done
find
$ dir 디렉토리에서 실행하십시오 .
find "$dir" -exec ./list_positional_parameters.sh '{}' ';' | less
예상 한대로 이름에 공백이 있는지 여부에 관계없이 모든 호출에 파일 이름 인 단일 매개 변수 만 있습니다.