각 찾기 결과에 대해 특정 명령을 어떻게 실행할 수 있나요?

각 찾기 결과에 대해 특정 명령을 어떻게 실행할 수 있나요?

이 명령을 사용하여 find찾은 모든 파일에 대해 특정 명령을 어떻게 실행할 수 있습니까? 질문의 목적에 따라 에서 찾은 모든 파일을 삭제하고 싶다고 가정해 보겠습니다 find.

답변1

편집하다:아래 답변은 일반적인 사용법을 설명하지만 파일과 디렉터리를 삭제하는 것은 특별한 경우라는 점에 유의해야 합니다. 해당 구성을 사용하는 대신 다음과 같이 1을 -execdir rm {} ';'사용하십시오 -delete.

find -iname '*.txt' -delete

이는 오류를 방지하고 일부 보안 문제를 해결하기 위해 삭제해야 하는 파일 및 디렉터리의 순서를 포함하여 생각하지 못했던 일부 극단적인 경우를 처리할 수 있습니다. 다른 사용 사례의 경우...

결과를 찾는 명령 실행을 처리하는 가장 좋은 방법은 일반적으로 명령에 다양한 -exec/ -ok술어를 사용하는 것입니다 find. 특히 1은 발견된 파일의 디렉터리 내에서 작동하고 일반적으로 다른 조건자보다 안전하기 때문에 가능할 때마다 1을 사용해야 합니다 -execdir(어리석은 실수가 재앙을 방지한다는 의미에서).

조건자 -exec뒤에는 실행하려는 명령이 오고, {}발견된 파일이 포함되어야 하는 위치를 나타내며, 각 파일에 대해 명령을 한 번 실행하거나 일치하는 모든 인수 목록을 대체하여 종료됩니다 find. 세미콜론 종결자는 따옴표로 묶여 있으므로 쉘은 이를 새 명령을 가리키는 구분자로 인식하지 못합니다. 및 의 파생물이나 이전 버전과 같은 일부 셸의 경우 인용이 필요할 수도 있습니다. 셸에 따라 , 또는 와 같은 대체 인용 형식을 사용할 수 있습니다. Bourne 또는 csh와 같은 쉘에 관용적입니다.';'+{}rcfish{}";"\;$';'\;

모든 텍스트 파일을 찾고 있다고 가정합니다.

find -iname '*.txt' -execdir rm {} ';'

다음은 GNU 매뉴얼의 관련 섹션입니다 find( man findGNU 시스템의 경우):

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of ‘;’ is encountered.  The string ‘{}’
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find.  Both  of  these
          constructions might need to be escaped (with a ‘\’) or quoted to
          protect them from expansion by the shell.  See the EXAMPLES sec-
          tion for examples of the use of the -exec option.  The specified
          command is run once for each matched file.  The command is  exe-
          cuted  in  the starting directory.   There are unavoidable secu-
          rity problems surrounding use of the -exec  action;  you  should
          use the -execdir option instead.


   -exec command {} +
          This  variant  of the -exec action runs the specified command on
          the selected files, but the command line is built  by  appending
          each  selected file name at the end; the total number of invoca-
          tions of the command will  be  much  less  than  the  number  of
          matched  files.   The command line is built in much the same way
          that xargs builds its command lines.  Only one instance of  ‘{}’
          is  allowed  within the command.  The command is executed in the
          starting directory.


   -execdir command ;

   -execdir command {} +
          Like -exec, but the specified command is run from the  subdirec-
          tory  containing  the  matched  file,  which is not normally the
          directory in which you started find.  This a  much  more  secure
          method  for invoking commands, as it avoids race conditions dur-
          ing resolution of the paths to the matched files.  As  with  the
          -exec action, the ‘+’ form of -execdir will build a command line
          to process more than one matched file, but any given  invocation
          of command will only list files that exist in the same subdirec-
          tory.  If you use this option, you must ensure that  your  $PATH
          environment  variable  does  not  reference  ‘.’;  otherwise, an
          attacker can run any commands they like by leaving an  appropri-
          ately-named  file in a directory in which you will run -execdir.
          The same applies to having entries in $PATH which are  empty  or
          which are not absolute directory names.

-iname또는 와 마찬가지로 -execdir이는 표준 옵션은 아니지만 많은 find구현에서 이를 지원합니다. 지원되는 경우 를 의미합니다 -depth.GNU 매뉴얼에서는 다음을 사용할 때 명시적으로 추가할 것을 find권장합니다 .-depth-delete이 사실을 잊지 않기 위해.

답변2

또 다른 접근 방식은 출력을 파이프하고 후속 명령을 사용하여 구문 분석하는 것입니다. 유일한 안전한 방법은 이 -print0옵션을 사용하는 것입니다. 이는 findnull 문자를 결과 구분 기호로 사용함을 나타냅니다. 수신 명령은 널로 구분된 입력을 인식할 수 있어야 합니다. 예:

find /home/phunehehe -iregex '.*\.png$' -print0 | xargs -0 file

-0옵션은 xargs입력이 널로 구분된 것으로 처리되도록 지시합니다.

답변3

이 작업만 수행해야 하는 경우 Find에는 삭제 명령이 내장되어 있습니다.

find . -name "*.txt" -delete

위 명령을 사용하면 발견된 모든 .txt 파일이 삭제됩니다.

답변4

나는 이 질문에 대한 답을 찾고 있었는데, 우연히 이 스레드를 발견했습니다. 이 답변을 통해 구현 방법에 대한 아이디어를 얻을 수 있었습니다. mediainfo모든 JPEG 파일을 찾고 싶다고 가정하십시오.

mediainfo "이는 일치하는 각 파일의 시작과 끝에 추가되며 "(가능한 경우 특수 문자를 이스케이프 처리하기 위해) 이를 스크립트에 넣고 스크립트를 실행합니다.

find . -name *.jpg | sed -e 's/^/mediainfo "/g;' | sed -e 's/$/"/g;' > foo.sh && sh foo.sh

문제가 걱정된다면 출력을 파일로 리디렉션하는 것을 건너뛰고 스크립트를 실행하기 전에 터미널에서 결과를 볼 수 있습니다.

관련 정보