find 명령을 사용하여 찾은 각 파일에 대해 Bash 기능을 실행합니다.

find 명령을 사용하여 찾은 각 파일에 대해 Bash 기능을 실행합니다.

현재 각 파일 이름을 한 줄에 성공적으로 인쇄하는 다음 명령이 있습니다.

find . -exec echo {} \;

find명령이 기능을 실행 하도록 논리를 분할하려고 합니다 . 기반으로이 문제나는 이것을 시도했습니다 :

my_function() {
    echo $1
}
export -f my_function
find . -exec bash -c 'my_function "$@"' bash {} +

그러면 다음과 같은 결과가 출력됩니다.

.

나는 또한 다음 $@으로 바꾸려고 시도했지만 $*그 결과 $1모든 파일에 개행 문자가 없었습니다. 각 파일을 확인하는 로직을 실행하고 싶기 때문에 $1한 번에 하나의 파일만 확인하고 싶습니다. 출력을 공백으로 분할하려고 시도했지만 for file in $1파일 이름에 공백이 있는 파일에서는 작동하지 않습니다. 명령으로 찾은 모든 파일에 대해 Bash 기능을 실행하는 방법은 무엇입니까 find?

편집: 이것은 내가 사용하는 전체 스크립트입니다. 아주 잘 작동하는 것 같습니다.

# Ensures that non-csproj text files are formatted with LF line endings.
format() {
    for pathname do
        if [[ $pathname == *"git"* ]]; then
            continue
        elif [[ $pathname == *"csproj"* ]]; then
            continue
        fi
        dos2unix $pathname
    done
}
export -f format
find . -exec bash -c 'format "$@"' bash {} \;

답변1

현재 디렉토리 안팎의 모든 일반 파일에서 실행하려면 dos2unix --newline이름에 문자열이 포함된 파일을 피하십시오 git.

find . -type f ! -name '*git*' -exec dos2unix --newline {} +

즉, 이름이 패턴과 일치하지 않는 모든 일반 파일을 찾아서 *git*가능한 dos2unix --newline한 큰 배치로 모두 한 번에 실행하십시오. 경로 이름에 이 문자열이 포함된 파일 (예: 디렉토리의 파일 ) 을 방지 ! -name '*git*'하려면 변경하세요 .! -path '*git*'git.git

디렉터리를 명시적으로 방지하되 .git이름에 포함될 수 있는 다른 항목을 포함하려면 다음을 수행하세요.git

find . -name .git -prune -o -type f -exec dos2unix --newline {} +

검색 트리에서 해당 경로 제거를 사용하여 호출된 find디렉토리가 입력되더라도 양식은 중지됩니다 ..git-prune


질문을 수정하기 전에 답변하세요.

귀하의 함수는 첫 번째 인수만 인쇄합니다. Dot은 에서 사용하는 최상위 검색 경로입니다 find. 디렉터리 항목에 대해 특정 필터링을 수행하지 않았기 때문에 통과할 것입니다(예: -type f일반 파일, -name또는 기타 종류의 find테스트에 대해서만).

함수가 각 인수를 인쇄하도록 하려면 다음을 사용하십시오.

my_function() {
    printf '%s\n' "$@"
}

printf사이에 줄 바꿈을 사용하여 각 매개변수를 인쇄해 보겠습니다 .

my_function() {
    for pathname do
        printf '%s\n' "$pathname"
    done
}

매개변수를 반복하고 printf각 매개변수에 대해 한 번씩 호출합니다.

다음과 같은 함수를 호출하면 제대로 작동할 것으로 예상됩니다.

my_function "$@"

인라인 bash -c스크립트에서. "$@"개별적으로 인용된 스크립트에 제공된 모든 인수로 확장됩니다 .

또 다른 접근 방식은 루프를 bash -c스크립트로 이동하는 것입니다.

for pathname do
    my_function "$pathname"
done

그럼 거기 있어요

my_function () {
    printf '%s\n' "$1"
}

이렇게 하면 각 경로 이름에 대해 함수를 한 번 호출하는 것과 같이 명시적으로 수행됩니다.

명령 find은 다음과 같습니다

find . -exec bash -c 'for pathname do my_function "$pathname"; done' bash {} +

또는 아마도 더 읽기 쉬울 것입니다.

find . -exec bash -c '
    for pathname do
        my_function "$pathname"
    done' bash {} +

그건 그렇고, 이것은 관련이 있습니다

shopt -s globstar nullglob dotglob

for pathname in ./**/*; do
    my_function "$pathname"
done

하지만 .처리가 되지 않습니다. 이를 사용하면 기능을 내보낼 필요가 없습니다 my_function.

함수 내부에 루프가 있으면(이 답변의 처음 두 코드 조각과 같이) 다음과 같이 단축됩니다.

shopt -s globstar nullglob dotglob

my_function ./**/*

관련 정보