find 명령의 -exec 옵션 내에서 별도의 파일 이름과 경로

find 명령의 -exec 옵션 내에서 별도의 파일 이름과 경로

탈출과 표현평가에 어려움을 겪고 있습니다. 하나의 파일에서 작동하고 stdout으로 출력되는 find... -exec COMMAND구조 내에서 명령을 실행하려고 합니다 . 명령줄에서 COMMAND이를 정상적으로 사용하려면 다음과 같이 새 파일로 리디렉션하면 됩니다.COMMAND

COMMAND inputfilename.md > outputfilename.md.conf

이것은 잘 작동합니다. 그러나 재귀적으로 반복하고 싶다면모두을 사용하여 디렉터리와 해당 하위 디렉터리의 파일을 find -exec검색할 때 제대로 리디렉션할 수 있도록 파일 이름과 경로를 분리하는 방법을 알 수 없는 것 같습니다. 예를 들어 이렇게 하면 오류가 발생합니다.

find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;

{}전체 파일 경로를 확장하기 때문입니다 . 나는 basename및 의 다양한 조합을 시도했지만 dirname평가할 수 없는 것 같습니다(대신 'basename' 등의 문자열만 얻습니다). 예를 들어 'basename'이라는 텍스트가 표시되기 때문에 작동하지 않았습니다.

find ./ *.md -not -path './/.git/*' -exec COMMAND  '{} > ~/wiki/newdirectory/''basename {}''.conf' \;

(이 오류를 반환합니다: 'No such file or directory - .//newdirectory/README.md.conf > ~/wiki/newdirectory/basename .//newdirectory/README.md.conf').

어떤 도움이라도 주시면 감사하겠습니다. 요약하자면 목표는 다음과 같습니다.

  1. *.md디렉터리에서 일치하는 모든 파일을 반복적으로 반복합니다.
  2. 각 반복에서 동일한 문자열이 있는 COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf곳을 실행합니다 .inputfile

감사해요!

답변1

무엇을 하든 쉘을 호출하여 명령 출력을 결과에 따라 위치가 달라지는 파일로 리디렉션해야 합니다 find.

find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND "$0" > ~/wiki/newdirectory/"${0##*/}.cong"' {} \;

{}쉘 스크립트 내부를 대체하지 마십시오 . 이것은 모든 시스템에서 지원되지 않으며, 심지어 그것이 있는 경우에도 일반적으로 작동하지 않습니다. 왜냐하면 파일 이름을 쉘 구문의 일부로 취급하기 때문입니다. 예를 들어 이라는 파일을 사용하면 ;rm -rf ~;.md모든 파일이 지워집니다.

${0##*/}순수한 문자열 조작을 사용하여 파일의 기본 이름을 얻습니다. 을 사용할 수도 있습니다 $(basename -- "$0").

답변2

find수락 하면 -execdir작동합니다.

find . -name '*.md' -not -path './/.git/*' -execdir COMMAND {} > ~/wiki/newdirectory/{}.cong \;

번갈아

find . -name '*.md' -not -path './/.git/*' -exec bash -c \
'for f; do COMMAND "$f" > ~/wiki/newdirectory/"${f##*/}".cong; done' _ {} +

관련 정보