리눅스에서 '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
'programing' 카테고리의 다른 글
mongo 명령 결과를 플랫 파일로 가져오는 방법 (0) | 2023.05.01 |
---|---|
Git Pull에서 Git 오류 발생(로컬 참조를 업데이트할 수 없음) (0) | 2023.05.01 |
C#의 DataTable에서 열 제거 (0) | 2023.05.01 |
무작위입니다. 세트에서 선택하시겠습니까?비단뱀 (0) | 2023.04.26 |
비웹 SQL 주입 (0) | 2023.04.26 |