검색 결과를 변수에 저장하고 출력 주위에 작은따옴표를 추가하여 파일 이름에 공백을 보호했습니다. 따라서 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
한 번에 최대한 많은 파일이 실행됩니다(따라서 여러 파일이 포함된 배치의 파일 이름도 출력하고, 파일 이름을 인쇄하지 않으려면 -h
GNU 또는 호환 옵션을 사용하십시오).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"
나는 이것이 나쁜 습관이라는 것을 알고 있습니다. 하지만 특정 사용 사례에서는 각 파일 이름에 대해 많은 작업을 수행해야 합니다. 단지 더듬거리는 것이 아닙니다. 이제 완벽하게 작동합니다.
감사해요!