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


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

함수는 첫 번째 인수만 인쇄합니다. 점은 에서 사용하는 최상위 검색 경로입니다 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 ./**/*

관련 정보