정규식을 사용하지 않고 여러 파일에서 문자열을 검색하시겠습니까?

정규식을 사용하지 않고 여러 파일에서 문자열을 검색하시겠습니까?

여러 파일에서 문자열을 검색할 수 있는 명령이 있지만 해당 명령(아마도 옵션으로 수정됨)이 정규식을 지원하지 않습니까? 이것이 정규식 사용을 피하고 특수 문자를 이스케이프 처리하지 않기를 바랍니다.

(디렉터리와 하위 디렉터리 내에서 재귀적으로 검색하는 옵션을 알아두면 좋을 것입니다.)

답변1

파일이 텍스트 파일이고 문자열에 개행 문자가 포함되어 있지 않은 경우 (forfixed-string) 옵션 grep과 함께 사용할 수 있습니다.-F

string='any /text\ *string* without newline (\n).'
find . -type f -exec grep -F -l -e "$string" {} +

이 문자열이 포함된 줄을 나열하는 텍스트 파일입니다.

(이것은 다음으로 제한됩니다.정기적인심볼릭 링크 확인 전 파일)

일부 grep구현에서는 텍스트가 아닌 파일(예: NUL, 바이트, 긴 행 또는 로케일에서 유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함된 파일)도 처리할 수 있습니다. 일부는 find, , 옵션을 사용하여 작업을 완료하기도 합니다. 그러나 비정규 파일의 경우 또는 디렉토리 트리를 내려갈 때 디렉토리에 대한 심볼릭 링크를 따르는지 여부에 따라 동작이 달라질 수 있습니다.-r-R-d recurse

busybox구현 시 grep이 옵션을 사용하여 개행 문자가 포함된 텍스트 문자열을 처리하도록 할 수 있습니다 -z. -z줄 대신 NUL로 구분된 레코드를 사용하는 것이지만, 정의에 따라 텍스트 파일은 NUL을 포함할 수 없으며 어쨌든 명령에 대한 인수로 NUL을 전달하거나 (를 제외하고 zsh) 이를 쉘 변수(예: )에 저장할 수 없습니다 $string.

그래서:

string='1
2
3'
busybox grep -raFlze "$string" .

모든 입력의 모든 문자열에 대해 작동합니다. 그러나 busybox grep -r(적어도 현재 버전에서는) 심볼릭 링크, 장치 등 모든 유형의 파일을 볼 수 있으므로 find다음을 사용하여 -r제한 할 수 있습니다.정기적인파일만:

find . -type f -exec grep -aFlze "$string" {} +

(일부 구현에는 파일 형식을 확인하는 기능 find도 있습니다.-xtype f뒤쪽에기호 링크 분석은 기호 링크 내의 일반 파일도 검색할 수 있습니다.

입력 파일에 NUL 바이트가 포함되어 있지 않으면 각 파일이 메모리에 전체적으로 로드되므로 매우 큰 파일에 맞게 확장되지 않음을 의미합니다.

NUL을 포함할 수 있는 임의의 데이터와 모든 크기의 파일에 대해 검색하려는 문자열을 파일에 저장하고 이를 사용하여 mmap()파일이 메모리에 로드되는 것을 방지할 수 있습니다. 당신 과 함께 perl다음과 같은 일을 할 수 있습니다:

needle_file=needle.bin # containing the string to search
size=$(wc -c < "$needle_file")

find . -type f -size "+$(( size - 1 ))c" -exec perl -MSys::Mmap -le '
  $needle = shift;
  open NEEDLE, "<", $needle or die "$needle: $!\n";
  mmap($needle, 0, PROT_READ, MAP_SHARED, NEEDLE);
  for (@ARGV) {
    if (open HAYSTACK, "<", $_) {
      mmap($haystack, 0, PROT_READ, MAP_SHARED, HAYSTACK);
      print if index($haystack, $needle) >= 0
    } else {
      warn "$_: $!\n"
    }
  }' -- "$needle_file" {} +

(이것은 Sys::Mmap핵심 모듈 중 하나가 아닙니다 . 데비안의 패키지에서 설치 perl해야 할 수도 있습니다 .)libsys-mmap-perl

하위 문자열 검색 알고리즘이 하위 문자열을 찾는 데 얼마나 효율적인지 알 수 없습니다 perl.index()

zshNUL은 해당 변수에 저장될 수 있으며 파일 내용은 변수에 매핑될 수 있으므로 다음을 수행할 수 있습니다.

zmodload zsh/mapfile
set +o multibyte
string=$'foo\nbar\0baz'
print -rC1 -- **/*(ND.L+$(($#string - 1))e['[[ $mapfile[$REPLY] = *$string* ]]'])

그러나 zsh아래에서는 작동 하지만 mmap()결국 파일 내용을 메모리에 복사하게 되며 쉘이기 때문에 perl.

답변2

무엇에 대해:

grep -inH -r "search_string" *

관련 정보