이 find
명령 의 파일 경로
find . -printf "%p \n"
특이한 문자(공백, 백슬래시, 큰따옴표 등)를 이스케이프 처리하지 마세요.
이 옵션 은 -ls
이스케이프된 경로를 인쇄하지만 .ls -dils
printf
효율적인 명령이 필요하므로 추가 명령을 실행해도 ls
도움이 되지 않으며 모든 추가 문자를 인쇄하지도 않습니다.
이스케이프된 경로를 출력하는 다른 (우아한) 방법이 있습니까 find
?
답변1
find -exec
일반적으로 모든 파일 이름에 대해 실행되는 명령을 사용 하거나 find -print0
nul 바이트로 구분된 항목을 읽을 수 있는 일부 명령(예: xargs -0
)으로 이름을 파이프하려고 합니다.
정말로 인용된 문자열을 원한다면 Bash에는 이를 수행할 수 있는 몇 가지 옵션이 있습니다:
$ find -exec bash -c 'printf "%s\n" "${@@Q}"' sh {} +
'./single'\''quote'
'./space 1'
$'./new\nline'
'./double"quote'
$ find -exec bash -c 'printf "%q\n" "$@"' sh {} +
./single\'quote
./space\ 1
$'./new\nline'
./double\"quote
이를 위해서는 쉘에 대한 추가 호출이 필요하지만 단일 exec로 여러 파일 이름을 처리하는 데 사용할 수 있습니다.
권한 비트(ACL 아님) 저장과 관련하여 다음을 수행할 수 있습니다(GNU find에서):
find -printf "%#m:%p\0" > files-and-modes
그러면 권한, 콜론, 파일 이름 및 nul 바이트가 포함된 항목이 출력됩니다(예: ). 그럴 것이다0644:name with spaces\0
아니요무엇이든 이스케이프하고 대신 파일 이름을 있는 그대로 인쇄합니다(단, 터미널로 출력하지 않는 한, 이 경우 최소한 줄 바꿈이 엉망이 됩니다.)
Perl 스크립트를 사용하여 결과를 읽을 수 있습니다.
perl -0 -ne '($m, $f) = split/:/, $_, 2; chmod oct($m), $f; ' < files-and-modes
또는 Bash에서는 거의 설명을 참조하십시오.
while IFS=: read -r -d '' mode file ; do
# do something useful
printf "<%s> <%s>\n" "$mode" "$file"
chmod "$mode" "$file"
done < files-and-modes
내가 테스트한 바에 따르면 개행, 따옴표, 공백 및 콜론 과 함께 작동합니다 . IFS=" "
이름에 뒤에 공백이 포함되어 있으면 설정에 따라 공백이 제거되므로 공백 이외의 다른 것을 구분 기호로 사용해야 합니다 .
답변2
이를 통해 zsh
다음을 수행할 수 있습니다.
print -r -- ./**/*(.D:q)
.
마찬가지로 will과 같은 숨겨진 파일과 -type f
참조 용도 D
포함됩니다 ( -style 참조를 사용하면 이것이 기대하는 참조 유형인지 알 수 없습니다).find
:q
zsh
다양한 스타일의 인용을 얻을 수 있습니다.
$ print -r -- ./**/*(.D:q)
./$'\200' ./a\ b ./é ./\"foo\" ./It\'s\ bad ./$'\n'
$ files=(./**/*(.D))
$ print -r -- ${(q)files}
./$'\200' ./$'\n' ./a\ b ./é ./\"foo\" ./It\'s\ bad
$ print -r -- ${(qq)files}
'./�' './
' './a b' './é' './"foo"' './It'\''s bad'
$ print -r -- ${(qqq)files}
"./�" "./
" "./a b" "./é" "./\"foo\"" "./It's bad"
$ print -r -- ${(qqqq)files}
$'./\200' $'./\n' $'./a b' $'./é' $'./"foo"' $'./It\'s bad'
( �
인쇄할 수 없는 \200 바이트에 대해 내 터미널 에뮬레이터가 표시하는 자리 표시자입니다.)
여기에서 복구 가능한 방식으로 권한을 저장하려면 다음을 수행하세요.
find . -type f -printf '%m\0%p\0' > saved-permissions
복원하려면(GNU 가정 xargs
):
xargs -r0n2 -a saved-permissions chmod
그러나 이는 chmod
파일당 하나의 호출을 실행하므로 매우 비효율적입니다. 다음과 같이 chmod
내장 쉘을 사용할 수 있습니다 .zsh
zmodload zsh/files
zmodload zsh/files
while IFS= read -rd '' mode && IFS= read -rd '' file; do
chmod $mode $file
done < saved-permissions
답변3
더 간단한 해결책을 찾았습니다.
find -exec echo \'{}\' \;
이를 사용하여 다른 프로그램으로 파이프할 수 있습니다.
find -exec echo \'{}\' \; | xargs ls
또는 echo 대신 간단히 임의의 명령을 사용하고 인수를 원하는 수만큼 추가할 수 있습니다.
find -exec mv \'{}\' somewhereelse \;
먼저 테스트하는 것을 잊지 마세요 echo
.
마지막은 작동하지 않습니다mv는 파일에 액세스하기 전에 따옴표를 제거하지 않으므로 대신 파이프를 사용하십시오.
find -exec echo mv \'{}\' somewhereelse \;| bash
답변4
왜 모든 캐릭터를 탈출하지 않습니까? 그런 다음 모든 작업(ls, rm, echo 등)에서 작동합니다.
find -name *.txt | sed -E 's/(.)/\\\1/g' | xargs ls
-exec
( 더 효과적이려면 이것을 형태에 맞게 조정해야 할 수도 있습니다 )