GNU 찾기: -exec에서 절대 및 상대 경로 가져오기

GNU 찾기: -exec에서 절대 및 상대 경로 가져오기

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. 이는 findGNU 구현뿐만 아니라 모든 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 fDfind


참고로 일반적으로 다음과 같습니다.

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포함되지 않으므로 문제가 없습니다 .//

관련 정보