명령에서 각 경로의 길이를 찾고 싶은 문제가 있습니다 find
. 나의 첫 번째 시도는 다음과 같은 것을 실행하는 것이 었습니다.
find . -exec sh -c "echo {} | wc -c" \;
이 답변에서 아이디어를 얻었습니다.. (위 명령은아니요내 문제는 단지 예를 들기 위한 것인데, 그것이 완전히 인공적이라는 것입니다. 또한 때로는 여러 개의 파이프가 필요할 수도 있습니다. )
하지만 실행하면 출력 경로에 있는 특수 문자로 인해 출력에 오류가 발생합니다. 안타깝게도 어떤 경로가 문제를 일으키는지 해결하는 방법을 모르며 오류 메시지에는 어떤 정보도 제공되지 않습니다. 에도 불구하고...
명령은
find
명령을 직접 실행합니다. 이 명령(filename 인수 포함)은 셸이나 파일 이름을 수정할 수 있는 다른 항목에 의해 처리되지 않습니다. 매우 안전합니다.
이것은 매우 편리한 것 같습니다. 사실 너무 편리해서 -exec sh -c ...
"치료"가 질병 자체보다 더 나쁜 것처럼 보입니다.
그래서 내 질문은, 내가 언제필요파이프 명령 find
과 내 경로에 특수 문자가 포함될 수 있나요?이 문제에 대한 보편적인 해결책이 있습니까?여러 가지 고려 사항을 생각할 필요가 없나요? 나는 배쉬를 사용하고 있습니다.
참고: 이것은 비슷한 질문입니다.find + exec 명령의 출력을 파이프로 보내는 가장 좋은 방법은 무엇입니까?차이점은 출력을 반드시 -exec
. find ... -exec ... foo {} | bar \;
나는 저항이 가장 적은 공통 경로를 찾고 있을 뿐이며 명령의 구조는 나에게 중요하지 않습니다.
답변1
파일 이름을 쉘 스크립트에 인수로 전달하십시오.
find . -exec sh -c 'printf "%s\n" "$1" | wc -c' sh {} \;
또는 쉘당 여러 파일을 호출합니다.
find . -exec sh -c 'for x in "$@"; do printf "%s\n" "$x" | wc -c; done' sh {} +
주문
find . -exec sh -c "echo {} | wc -c" \;
파일 이름은 쉘 명령줄에 그대로 삽입됩니다. 공백이나 쉘 특정 문자가 포함되지 않은 파일 이름에만 작동합니다. 예를 들어, Don't stop me now.mp3
같은 것은 this&that.txt
문제를 일으킬 수 있습니다. (첫 번째는 끝나지 않은 인용 문자열을 생성하고, 두 번째는 echo
백그라운드에서 시작된 다음 이름이 지정된 명령을 실행하려고 시도합니다 that.txt
.)
반면에 sh -c ... sh {} \;
(또는 파일 이름이 다른 인수로 쉘에 전달 ... {} +
된 find
경우 위치 인수에서 사용할 수 있으며 쉘 구문과 혼합하지 않고 사용할 수 있습니다. ( "$1"
첫 번째의 경우 "$@"
전체에 대해) 목록 .)
파일 이름 길이를 확인하는 경우 "${#var}"
길이를 다음과 같이 제공하는 것을 제외하고 셸에서 가져올 수도 있습니다.수치현재 로케일을 기준으로 동시에 wc -c
계산바이트.
답변2
-exec echo {}
피하고 있음에도 불구하고껍데기처리, 여러 버전에코mangle 매개변수에는 백슬래시 또는 선행 하이픈이 포함됩니다. (물론 wc
원하는대로 전송되지는 않습니다.)
모든 경로명에 대해 이 작업을 수행하는 대신 wc
여러 입력 줄(레코드라고도 함)을 처리하도록 설계된 프로그램을 사용하겠습니다.
find . | awk '{print length}' # basecase
# if in a multibyte locale and you want bytes not chars
# prefix the awk with LANG=C (or any other singlebyte)
# if pathname (ever) contains newline, and you have GNU find (and awk?)
find . -print0 | awk -vRS='\0' '{print length}'
또는 기본값은 바이트이지만 개행이 허용되는 경우를 perl -nle 'print length'
처리하는 방법을 찾지 못했습니다 .-print0