변수를 확장하여 공백이 포함된 파일 찾기

변수를 확장하여 공백이 포함된 파일 찾기

검색 결과를 변수에 저장하고 출력 주위에 작은따옴표를 추가하여 파일 이름에 공백을 보호했습니다. 따라서 for 루프는 완벽하게 작동합니다.

내 문제는 파일 중 하나를 grep하려고 할 때 실제로 파일 이름의 일부로 작은따옴표가 있기 때문에 "파일이 존재하지 않습니다"라는 메시지가 표시된다는 것입니다.

어떻게 해야 이 문제를 극복할 수 있나요?

all_files=$(find . -type f -printf "'%p'")

for file in $all_files
do
       grep 'hello' $file ### this says "file.not found because of the single quotes
done

답변1

.txt 출력에 따옴표를 추가하여 파일 이름 값을 보호하지 않았습니다 find. 루프는 여전히 'a filename'반복되어야 하는 두 가지 항목 으로 처리됩니다 . 알다시피, 따옴표도 문자열의 일부가 됩니다.

대신 grep다음을 실행하세요 find.

find . -type f -exec grep 'hello' {} \;

이는 grep발견된 각 파일에 대해 한 번씩 실행됩니다.

find . -type f -exec grep 'hello' {} +

이렇게 하면 grep한 번에 최대한 많은 파일이 실행됩니다(따라서 여러 파일이 포함된 배치의 파일 이름도 출력하고, 파일 이름을 인쇄하지 않으려면 -hGNU 또는 호환 옵션을 사용하십시오).grep

여전히 GNU를 사용하고 있습니다 grep.

grep -D skip -r 'hello' .

이는 grep현재 디렉토리에서 재귀적으로 실행되어 비정규 파일( 과 마찬가지로 -type f) 을 건너뛰지 find만 여전히 일반 파일에 대한 기호 링크를 찾습니다( GNU 를 사용하는 것과 같습니다 find -xtype f).

답변2

나중에 반복하기 위해 파일 목록을 저장하려면 배열에 저장하는 것이 좋습니다.

그리고 bash:

readarray -td '' all_files < <(find . -type f -print0)
for file in "${all_files[@]}"; do
  grep hello "$file"
done

( zsh동일하지만 보너스로 정렬된 목록을 얻음):

all_files=(./**/*(ND.))
for file ($all_files) grep hello $file

답변3

"hello" 패턴으로 모든 파일 이름을 인쇄합니다.

find . -type f -print0 | xargs -0 -L1 grep -l 'hello'

또는 find인라인 으로grep

find . -type f -exec grep -l 'hello' {} \;

또는 더 간단합니다(일반 파일만 있는 경우).

grep -Rl 'hello' .

답변4

내가 이 문제를 어떻게 해결했는지에 관심이 있는 분들을 위해 다음과 같은 결론을 내렸습니다.

all_files=$( find . -type f -name *.txt -printf '%p' )

while read file
do
        grep 'hello' "$filename"
        .....
done <<< "$all_files"

나는 이것이 나쁜 습관이라는 것을 알고 있습니다. 하지만 특정 사용 사례에서는 각 파일 이름에 대해 많은 작업을 수행해야 합니다. 단지 더듬거리는 것이 아닙니다. 이제 완벽하게 작동합니다.

감사해요!

관련 정보