programing

리눅스에서 'find-exec' 셸 함수

muds 2023. 5. 1. 22:04
반응형

리눅스에서 'find-exec' 셸 함수

당신이 할 수 있는 방법이 있습니까?find제가 쉘에서 정의한 기능을 실행하는 것?

예:

dosomething () {
  echo "Doing something with $1"
}
find . -exec dosomething {} \;

그 결과는 다음과 같습니다.

find: dosomething: No such file or directory

당신이 할 수 있는 방법이 있습니까?find-exec보기 위해dosomething?

셸만 셸 함수를 실행하는 방법을 알기 때문에 셸 함수를 실행하려면 셸을 실행해야 합니다.을 또한내기다표합니다야시로 .export -f그렇지 않으면 하위 셸이 상속하지 않습니다.

export -f dosomething
find . -exec bash -c 'dosomething "$0"' {} \;
find . | while read file; do dosomething "$file"; done

Jac의 대답은 훌륭하지만 쉽게 극복할 수 있는 몇 가지 함정이 있습니다.

find . -print0 | while IFS= read -r -d '' file; do dosomething "$file"; done

이렇게 하면 라인피드 대신 null을 구분 기호로 사용하므로 라인피드가 있는 파일 이름이 작동합니다.또한 다음을 사용합니다.-r백슬래시 이스케이프를 비활성화하는 플래그이며, 플래그가 없으면 파일 이름의 백슬래시가 작동하지 않습니다. 또한맑음을 지웁니다.IFS이름의 잠재적인 후행 공백이 삭제되지 않도록 합니다.

에 추가{}아래와 같이:

export -f dosomething
find . -exec bash -c 'dosomething "{}"' \;

은 이게하반환특수문인수다니정오됩에서 된 특수 문자로 합니다.find예를 들어 이름에 괄호가 있는 파일입니다.

대량 처리 결과

위해 효성향상위많사이람들은해율을이사를 사용합니다.xargs대량으로 결과를 처리하는 것은 매우 위험합니다.그 때문에 대체 방법이 도입되었습니다.find대량으로 결과를 실행합니다.

방 법 POSIX-의 요 사 POSIX-구 과 주 가 사 함 과 있 습 니 수 다 될 제 공 께 항 의 지 몇 은 은 항 같 예 를 어 들 ▁pos ▁for ▁note ats ment ▁like▁ ▁cave ▁might ▁in▁come ▁method▁with▁some니습다있 ▁a ▁example방▁though▁thatix▁this수법과 같은 몇 가지 주의가 있을 수 있습니다.find가지기 위해{}명령이 끝날 때.

export -f dosomething
find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +

find는 의일 단호 대인한많결것전다입니달은의 단일 할 것입니다.bash 리고그고.for은 이 -loop을 합니다.dosomething그것들 각각에.

은 위의솔루다인시작수다니에서 합니다.$1그것이 바로 그것이 있는 이유입니다._은 (을 나타냄)$0).

결과를 하나씩 처리하는 중

같은 방식으로, 저는 받아들여진 최고 답변이 다음과 같이 수정되어야 한다고 생각합니다.

export -f dosomething
find . -exec bash -c 'dosomething "$1"' _ {} \;

논쟁은 항상 다음에서 시작해야 하기 때문에, 이것은 더 제정신이 아닙니다.$1▁also다니합▁but를 사용하기도 합니다.$0파일 이름이 에 의해 반환된 경우 예기치 않은 동작으로 이어질 수 있습니다.find셸에 특별한 의미가 있습니다.

스크립트가 자체를 호출하여 발견된 각 항목을 인수로 전달하도록 합니다.

#!/bin/bash

if [ ! $1 == "" ] ; then
   echo "doing something with $1"
   exit 0
fi

find . -exec $0 {} \;

exit 0

스크립트를 실행할 때 스크립트는 원하는 항목을 찾고 각 검색 결과를 인수로 전달합니다.스크립트가 인수를 사용하여 실행되면 인수에 대한 명령을 실행한 다음 종료됩니다.

현재 디렉터리에 있는 모든 파일에 대해 지정된 명령을 실행할 Bash 함수를 찾는 분들을 위해 위의 답변 중 하나를 컴파일했습니다.

toall(){
    find . -type f | while read file; do "$1" "$file"; done
}

공백이 포함된 파일 이름으로 구분됩니다(아래 참조).

다음 함수를 예로 들어 보겠습니다.

world(){
    sed -i 's_hello_world_g' "$1"
}

현재 디렉터리의 모든 파일에서 "안녕"의 모든 인스턴스를 "월드"로 변경하고 싶다고 합니다.제가 할 일은:

toall world

파일 이름의 기호를 안전하게 사용하려면 다음을 사용합니다.

toall(){
    find . -type f -print0 | while IFS= read -r -d '' file; do "$1" "$file"; done
}

(하지만 당신은 필요합니다.find그것은 취급합니다.-print0 GNU »: GNUfind).

셸을 사용하는 수락된 답변에 대한 경고입니다. 질문에 잘 대답하지만 검색 결과에 대해 일부 코드를 실행하는 가장 효율적인 방법은 아닐 수 있습니다.

간단한 루프 케이스를 포함한 모든 종류의 솔루션에 대한 벤치마크가 있습니다. (1465개의 디렉터리, 표준 하드 드라이브의 경우 armv7l GNU/Linux synology_armada38x_ds218j)

dosomething() { echo $1; }

export -f dosomething
time find . -type d -exec bash -c 'dosomething "$0"' {} \; 
real    0m16.102s

time while read -d '' filename; do   dosomething "${filename}" </dev/null; done < <(find . -type d -print0) 
real    0m0.364s

time find . -type d | while read file; do dosomething "$file"; done 
real    0m0.340s

time for dir in $(find . -type d); do dosomething $dir; done 
real    0m0.337s

"find | while"과 "for loop"은 속도 면에서 가장 좋고 유사한 것 같습니다.

그런 식으로 함수를 실행할 수 없습니다.

이 문제를 해결하기 위해 셸 스크립트에 기능을 배치하고 다음에서 호출할 수 있습니다.find

# dosomething.sh
dosomething () {
  echo "doing something with $1"
}
dosomething $1

이제 검색에서 다음과 같이 사용합니다.

find . -exec dosomething.sh {} \;

일부 다른 답변에 대한 추가 및 설명 제공(대량 옵션을 사용하는 경우)exec또는execdir(-exec command {} +인수를 하려면 )의 .$0와 함께bash -c.

더해 보세요. 이 는 좀 더 구 명 를 어 고 같 하 습 니 다 과 면 다 음 려 령 의 아 체 로 래 적 으 같 니 다 , 습 ▁below ▁more ▁command ▁the ▁uses 좀▁considerbash -c위에서 제안한 대로 파일 경로가 '.dll'로 끝나는 것을 각 디렉터리에서 반복합니다.

find "$1" -name '*.wav' -execdir bash -c 'echo "$@"' _ {} +

Bash 설명서에는 다음과 같이 나와 있습니다.

에 약에만.-c옵션이 있으면 첫 번째 비옵션 인수 command_string에서 명령을 읽습니다. command_string 뒤인있으위면에, 시니다같합작으로 하여 위치 됩니다.$0.

여기서,'echo "$@"'이며, "는 " " 입니다._ {}명령 문자열 뒤의 인수입니다.:$@는 1부터 시작하는 모든 위치 매개 변수로 확장되는 Bash의 특수 위치 매개 변수입니다.또한 다음과 같은 기능을 사용합니다.-c 첫 parameter 옵 인 첫 번 수 가 위 치 매 개 변 됩 니 할 당 다 에 수 션 째 , ▁is ▁to ▁option 니 ▁position 됩 ▁the ▁assigned 옵 다$0.

즉, 모든 위치 매개 변수에 액세스하려는 경우$@매개 변수는 다음에서 시작합니다.$1 위로 그이상이.그것이 도미닉의 대답이 다음과 같은 이유입니다._은 파라미터 매개변수채더인미수다니입우를 위한 입니다.$0할 수 .$@들어 변수 예들 파확장또는터미라어를for그 대답처럼 반복합니다.

인 물론인, 된답유사게하과변정인▁to유,게▁of▁the,▁answer정하사,,bash -c 'shell_function "$0" "$@"'또한 명시적으로 전달함으로써 작동합니다.$0하지만 다시 말하지만, 당신은 명심해야 할 것입니다.$@예상대로 작동하지 않습니다.

기능을 별도의 파일에 넣고 다음을 수행합니다.find그것을 실행하기 위해.

된 셸 .find그들을 절대 볼 수 없을 것입니다.

은 두한하는 것이라고 합니다.do:

func_one () {
  echo "The first thing with $1"
}

func_two () {
  echo "The second thing with $1"
}

find . -type f | while read file; do func_one $file; func_two $file; done

직접적으로는 안해, 안했어.찾기가 셸이 아닌 별도의 프로세스에서 실행되고 있습니다.

하는 셸 .-exec 거그거.

사용하지 않을 것입니다.-exec다같이.xargs 사용:

find . -name <script/command you're searching for> | xargs bash -c

언급URL : https://stackoverflow.com/questions/4321456/find-exec-a-shell-function-in-linux

반응형