grep 검색 결과에서 공백을 탈출하는 방법은 무엇입니까? (파일 이름)

grep 검색 결과에서 공백을 탈출하는 방법은 무엇입니까? (파일 이름)

내가 이것을 실행할 때 :

for f in $(grep -r --include=*.directory "search-string"); do echo $f; done;

내가 얻은 검색 결과는 검색 결과 파일 이름에서 공백으로 구분됩니다.

grep 검색 결과에서 공백을 탈출하는 방법은 무엇입니까?

답변1

배열의 파일 목록을 원하고 bash 셸(버전 4.4 이상)을 사용하는 경우 다음을 수행할 수 있습니다.

readarray -td '' files < <(
  grep -rlZ --include='*.directory' "search-string" .
)

쉘 포함 zsh:

files=(${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"})

다음을 사용하여 반복합니다.

for file in "${files[@]}"; do
  printf '%s\n' "$file"
done

를 사용하면 zsh다음을 통해 중간 배열을 건너뛸 수 있습니다.

for file in ${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"}; do
  printf '%s\n' "$file"
}

따옴표가 없는 단어 확장(예: $f또는 $(...))은 매우 특별한 의미를 가지며 bash일반적으로 원하는 것이 아니며 파일 이름은 NUL을 제외한 모든 바이트 값을 포함할 수 있으므로 표현할 때 NUL이라고도 0해도 0괜찮습니다. 고유하게 구분된 파일 경로 목록 구분된 바이트 스트림으로 사용하는 것이 안전합니다. 이것이 GNU의 -Z/ 옵션의 목적입니다.--nullgrep

다음과 같은 간단한 셸을 사용하면 GNU의 출력을 사용하여 셸에서 참조하는 파일 이름 목록을 생성하여 셸 코드로 평가할 dash수 있습니다.gawkgrepsh

eval set -- "$(
  grep -rlZ --include='*.directory' "search-string" . |
    gawk -v RS='\0' -v ORS=' ' -v q="'" '
      {gsub(q, q "\\" q q); print q $0 q}'
)"

for file do
  printf '%s\n' "$file"
done

파일 이름에 개행 문자가 포함되지 않는다고 보장할 수 있다면 다음과 같이 단순화할 수 있습니다.

IFS='
'
set -o noglob

for file in $(grep -rl --include='*.directory' "search-string" .); do
  printf '%s\n' "$file"
done

set -o noglob파일 이름에 *, ?, [( \셸 및 셸 버전에 따라 , 및 더 많은 glob 연산자)도 포함되지 않는다고 보장할 수 있으면 건너뛸 수 있습니다.

답변2

파일 경로에 개행 문자가 없다고 확신하는 경우 단어 분할을 개행 문자로 제한할 수 있습니다.

oldIFS="$IFS"
IFS=$'\n'
for f in $(grep -r --include=*.directory "search-string"); do
    echo "$f"
done
IFS="$oldIFS"

답변3

grepGNU 사람들은 파일을 찾는 옵션을 제공했을 때 정말 실수를 저질렀습니다. sed, awk, cat, tr, wc 및 기타 모든 UNIX 도구에 대해 동일한 기능을 제공할 계획이 없으며 기존 도구가 수행하는 다른 작업(예: 파일 정렬)에 grep 옵션을 제공할 계획도 없기를 바랍니다. ), 문자열 바꾸기, 문자 번역, 문자 수 계산 등을 수행합니다. 다음을 수행할 수 있는 아주 좋은 UNIX 도구가 있습니다.찾다파일의 이름은 매우 분명합니다 find.

while IFS= read -rd '' file; do
    echo "$file"
done < <(find . -name '*.directory' -exec grep -lZ 'search-string' {} +)

위의 경우 NUL 종료 입력/출력을 사용하려면 (이미 사용 중인) GNU 도구가 필요합니다. 파일 이름에 개행 문자가 없으면 표준 도구를 대신 사용할 수 있습니다.

관련 정보