![GNU 찾기: -exec에서 절대 및 상대 경로 가져오기](https://linux55.com/image/122382/GNU%20%EC%B0%BE%EA%B8%B0%3A%20-exec%EC%97%90%EC%84%9C%20%EC%A0%88%EB%8C%80%20%EB%B0%8F%20%EC%83%81%EB%8C%80%20%EA%B2%BD%EB%A1%9C%20%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0.png)
echo
절대 경로와 상대 경로를 사용하는 명령을 실행하고 싶습니다(아닙니다!).
이 두 매개변수를 어떻게 얻나요?
시도:
d=/tmp/foo;
find "$d" -type f -exec bash -c 'echo d=${1:${#d}} 1="${1%/*}"' bash {} \;
(저는 재귀적이고, 파일로 제한할 수 있고, 파일 이름으로 필터링할 수 있고, 너무 많은 쉘을 생성하지 않기 때문에 GNU find를 좋아합니다.)
예상하다:
mkdir -p /tmp/foo/bar/can/haz; touch /tmp/foo/bar/can/haz/bzr.txt
# cmd is run, output is:
d=bar/can/haz 1=/tmp/foo/bar/can/haz
답변1
내 보내면 d
인라인 스크립트에서 사용할 수 있습니다 bash
. bash
여기서는 전혀 필요하지 않습니다 . 귀하의 (희망적으로 더 얇고/더 빠른) sh
제품도 동일한 작업을 수행합니다. 또한 각 파일에 대해 셸을 실행할 필요가 없습니다. 다음 변형을 사용하여 더 많은 파일을 인라인 스크립트에 전달할 수 있습니다 -exec cmd {} +
.
d=/tmp/foo
export d
find "$d" -type f -exec sh -c '
for file do
relative=${file#"$d/"}
dir=${file%/*}
relative_dir=${relative%/*}
relative_dir=${relative_dir:-.}
printf "%10s: %s\n" full "$file" \
relative "$relative" \
dir "$dir" \
reldir "$relative_dir"
done' sh {} +
이것은 만든다:
full: /tmp/foo/bar/can/haz/bzr.txt
relative: bar/can/haz/bzr.txt
dir: /tmp/foo/bar/can/haz
reldir: bar/can/haz
그러나 상대 경로만 필요한 경우 다음을 수행하는 것이 더 간단할 수 있습니다.
(cd -P -- "$d" && find . -exec sh -c 'for file do...' sh {} +)
또한 전달되는 명령 매개변수가 sh
짧아 지므로 find
더 많은 매개변수가 전달될 수 있습니다 sh
.
귀하의 명령이나 내 명령에는 GNU와 관련된 내용이 없습니다 find
. 이는 find
GNU 구현뿐만 아니라 모든 POSIX 호환 구현에서 작동합니다 . 귀하의 질문에서 POSIX가 아닌 유일한 부분은 POSIX의 연산자가 아닌 Korn 쉘 연산자입니다 bash
.${1:offset}
sh
파일 유형을 지정할 수 있는 재귀적 파일 조회에 대해서는 다음도 참조하세요 zsh
.
(cd -P -- "$d" &&
for file (**/*(ND.)) {
dir=$file:h
printf '%10s: %s\n' relative $file reldir $dir
})
위의 내용 은 's (일반 파일만 .
해당)와 동일 하지만 숨겨진 파일을 포함하는 경우 에도 마찬가지입니다 .find
-type f
D
find
참고로 일반적으로 다음과 같습니다.
c=$a$b; d=${c:${#a}}
[ "$b" = "$d" ] && echo yes
${#var}
and ${var:offset}
연산자가 다음과 동일하기 때문에 "yes" 출력이 보장되지 않습니다.수치, 아니요바이트.
a
예를 들어, UTF-8 로케일에서는 및 다음 값에 대해 yes를 인쇄하지 않습니다 b
.
a=$'St\xc3' b=$'\xa9phane'
이를 통해 $c
내 이름( Stéphane
)에는 해당 문자의 절반이 포함되고 $a
나머지 절반은 포함됩니다(2 문자와 1 바이트는 유효한 문자를 형성하지 않지만 여전히 계산됩니다).é
$b
${#a}
3
그럴 $d
거에요 phane
, 아니 $'\xa9phane'
.
그러나 특정 경우에는 시스템 로케일에서 일반적으로 사용 가능한 문자 세트 중 인코딩을 포함하는 문자 이외의 문자가 d=$a/$b
포함되지 않으므로 문제가 없습니다 ./
/