찾기에서 찾기 실행

찾기에서 찾기 실행

"linux run find on find"에 대한 웹 검색을 수행했지만 관련 결과가 나오지 않았습니다. 찾기에서 파일 목록을 작성한 다음 해당 목록에서 찾기를 다시 실행하고 싶습니다.

몇 가지 "어리석은" 버그를 수정한 후 명령줄 작업 경험이 거의 없었기 때문에 최종 명령은 다음과 같았습니다.

find "path1" -size 0 -printf "%f\0" | xargs -0 --max-args=1 --verbose find "path2" -exec ls -l {} \\\; -name

As --verbose, 명령이 다음과 같이 실행되는 것을 봅니다.

find path -exec ls -l {} \; -name foundfilename

그리고 출력 missing argument to exec.

결과 명령 build를 직접 실행 하면 xargs(어떤 이유로 큰따옴표 xargs --verbose를 추가하면 출력이 누락되지만 실제로는 find에 공백이 포함된 경로에 문제가 없으므로 실제로 작동합니다.)

find "path" -exec ls -l {} \; -name foundfilename

출력은 다음과 같습니다 path.

  1. xargs와 직접 실행의 결과가 다른 이유는 무엇입니까 find?
  2. 외모는 -exec앞에 올 수 없습니다 -name. 맞나요?
  3. 마지막으로 요점: find결과를 서로 올바르게 실행하는 방법은 무엇입니까 find?

시스템: 리눅스 민트 19.2

두 번째 질문을 명확히하기 위해 의견 뒤에 추가되었습니다.

내가 달리면

find "path" -name foundfilename -exec ls -l {} \;

예상대로 발견되어 나열된 여러 파일의 출력 ls, 즉 두 번째 질문을 얻습니다.

.12/media/ramdrive

marina@tpx:~$ find /media/ramdrive -exec ls {} \; -name 1
1  2
/media/ramdrive/2
/media/ramdrive/1
marina@tpx:~$ find /media/ramdrive -name 1 -exec ls {} \;
/media/ramdrive/1

그 남자는 다음을 발견했습니다.

-명령을 실행합니다. 명령을 실행합니다. 상태 0이 반환되면 true입니다. find에 대한 다음 인수는 모두 ;' is encountered. The string{}'로 구성된 인수가 일부 버전의 find에서와 같이 별도의 인수가 아닌 명령에 대한 인수에 나타나는 현재 파일 이름으로 대체될 때 까지 명령에 대한 인수로 처리됩니다 . 두 구성 모두 셸 확장으로부터 보호하기 위해 이스케이프('' 사용)하거나 인용해야 할 수 있습니다. -exec 옵션 사용에 대한 예는 예 섹션을 참조하세요. 일치하는 각 파일에 대해 지정된 명령이 한 번 실행됩니다. 이 명령은 시작 디렉터리에서 실행됩니다. -exec 작업을 사용할 때 피할 수 없는 보안 문제가 있으므로 -execdir 옵션을 사용해야 합니다.

-exec왜 일치 옵션 이전에 있을 수 없는지 이해가 되지 않습니다 .

실제로 "별도의 인수뿐만 아니라 명령 인수의 어느 곳에나 나타납니다"가 무엇을 의미하는지 이해하지 못합니다.

두 가지를 더 추가합니다.
그래도 해결책을 찾았습니다.

find "path1" -size 0 -printf "%f\0" | xargs -0 --max-args=1 --verbose find "path2" -name | xargs ls -l

그러나 find의 기본 인쇄는 결과를 인용하지 않으므로 공백이 있는 경로에서는 실패합니다. 따옴표를 추가하는 유틸리티가 있나요?

답변1

xargs직접 find조작과 결과가 다른가요?

때를유형 find path -exec ls -l {} \; -name foundfilename쉘에서는 쉘을 \;" ;명령에 전달됨"으로 발음합니다. 그냥 ;입력하면 명령 구분 기호가 됩니다. 백슬래시는 쉘에 의해 "먹히고" 이에 따라 동작이 변경됩니다 ;.

언제 xargs말했어?달리다 find path -exec ls -l {} \; -name foundfilename, 백슬래시를 제거하기 위해 실제로 셸 없이 명령에 전달됩니다 \;(즉, 에 전달됨 ). find따라서 \;오류는 다음과 같습니다. or 을 -exec기대하면 둘 중 하나도 얻지 못하므로 "exec에 대한 인수가 누락되었습니다".;+


외모는 -exec앞에 올 수 없습니다 -name. 맞나요?

잘못된. 그것은 할 수 있습니다. 아닐 수도 있습니다. 원하는 작업에 따라 다릅니다. 두 명령의 서로 다른 결과는 쉽게 설명됩니다. 이 두 명령은 다음과 같습니다.

find /media/ramdrive -exec ls {} \; -name 1
find /media/ramdrive -name 1 -exec ls {} \;

중요한 사실:

  • -exec그것은 또한 테스트이다. 내부 명령이 반환되는 경우에만 성공합니다 0.
  • -o테스트는 ( 논리적 OR) 또는 -a(논리적 AND) 연산자로 연결됩니다 . -a귀하의 경우와 같이 연산자가 누락되었다고 가정하십시오.
  • -test1 -o -test2또는 를 사용 -test1 -a -test2하고 -test1먼저 테스트하세요. 결과가 그것만으로 결정되면 -test1실행 -test2되지 않습니다. 특히, 이는 -test1 -a -test2성공할 경우에만 실행됨을 의미합니다(우리는 이미 결과를 알고 있으므로 실패할 경우에는 필요하지 않습니다: 실패).test2-test1-test2

전체 테스트가 -exec ls {} \; -name 1(예: -exec ls {} \; -a -name 1) 인 경우 -exec각 후보를 테스트하세요. 이것은 이미 표준 출력으로 무언가를 인쇄합니다. 성공한 각 후보에 대해 ls다른 테스트가 실행되지만 다른 테스트에서는 아무것도 인쇄되지 않고 추가 테스트/작업이 없기 때문에 중요하지 않습니다(기본값은 -print이전에 의해 억제됨 -exec).

전체 테스트가 -name 1 -exec ls {} \;(예: -name 1 -a -exec ls {} \;) 인 경우 -name각 후보를 테스트하세요. 테스트는 아무 것도 인쇄하지 않지만 결과에 따라 -exec실행 여부가 결정됩니다. 따라서 lsiff를 성공적으로 실행하면 성공한 -name내용이 인쇄됩니다 .-name


find다른 결과를 올바르게 실행하는 방법은 무엇입니까 find?

다른 내 find에서 실행될 수 있습니다 . 예를 들어 다음과 같은 디렉터리에서 모든 심볼릭 링크를 찾습니다 .-execfindlib

find / -type d -name lib -exec find {} -type l \;

/lib//var/lib/등 의 결과를 얻을 수 있습니다./usr/lib/

몇 가지 질문이 있습니다:

  • 이는 find외부의 결과를 기반으로 내부를 실행합니다 find. 한 결과의 모든 결과를 한 번에 사용하려면 find, 즉 다음을 사용하십시오.하나의다른 find.
  • 내부 find도 실행해야 하는 경우 , ( 로 입력 ) 또는 를 -exec전달하는 직접적인 방법이 없습니다 . 이는 외부에서 해석되기 때문입니다 . 한 가지 해결책은 다음을 사용하는 것입니다 .{};\;+findxargs훌륭해), 일반적으로 줄바꿈이 포함된 이름에 실패하지 않도록 POSIX가 아닌 옵션이 필요합니다. 또 다른 해결책은 find두 개의 s 사이에 쉘을 생성하는 것입니다(예:이 다른 답변내 기사를 작성하는 동안 이 문제가 발생했으며 해당 해결 방법을 반복하지 않겠습니다.)

"별도의 인수뿐만 아니라 명령 인수의 어느 곳에나 나타납니다"가 무엇을 의미하는지 이해하지 못합니다.

POSIXfind연장 필요홀로 {}. {}.txt"이 두 문자가 대체되는지 또는 문자열이 변경되지 않고 사용되는지 여부는 foo{}bar구현에 따라 정의됩니다" 와 같은 매개변수의 경우 . find귀하의 버전은 또는 같은 인수 find로 대체되며 {}매뉴얼에는 이에 대해 명확하게 명시되어 있습니다.{}.txtfoo{}bar

답변2

그냥 해:

find path1 -size 0 -exec sh -c '
  for file do
    find path2 -name "${file##%/}" -exec ls -ld \{\} +
  done' sh {} +

(빈 파일 이름에 와일드카드나 백슬래시가 포함되어 있지 않다고 가정하면 -name해당 인수는 다음과 같이 처리됩니다.와일드카드 패턴).

GNU에서 왔기 때문에 다음 으로 find대체할 수도 있습니다 ( 표준 은 아니지만 GNU에 특정 하지만 출력 형식은 구현에 따라 약간씩 다르지만 이식성이 더 좋음).-exec ls -ld \{\} +-ls-printf-ls-printf-ls

더 일반적 으로는 GNU 스타일을 사용하고 NUL로 구분된 레코드(예: using 또는 레코드)를 출력하지 않는 한 find출력을 레코드로 파이프 하고 싶지 않습니다. 대부분의 경우 파이프로 연결하는 것보다 사용하는 것이 더 좋습니다. 더 일반적으로,xargsxargs -r0find-print0-printf '%f\0'-exec ... {} +xargs카밀의 대답귀하의 접근 방식의 문제점은 잘 설명되어 있으므로 여기서는 반복하지 않겠습니다.

zsh여기서 대신 쉘을 사용할 수 있습니다 .

for file (path1/**/*(NDL0)) ls -ld path2/**/$file:t(DN)

(와일드카드 문제는 없습니다)

답변3

-I@muru의 팁에 따라 에서 사용되는 xargs작업 명령( find및 의 GNU 구현을 가정 xargs)은 다음과 같습니다.

find "path1" -size 0 -printf "%f\0" |
  xargs -r0 -I mystr find "path2" -name mystr -exec ls -ld {} +

-name( 인수는 다음과 같이 해석되므로 빈 파일의 이름에는 와일드카드가 포함되지 않은 것으로 가정합니다.와일드카드 패턴)

관련 정보