다음과 같은 문자열이 있습니다 "thisissometext"
. 이 문자열을 포함하는 지정된 디렉터리 내에서 (재귀적으로) 모든 텍스트 파일을 찾고 싶거나 중간에 공백 및/또는 개행 문자가 있는 변형을 찾고 싶습니다. 예를 들어, "this is sometext"
또는 가 "this\n issometext"
포함 된 텍스트 파일이 "this\n isso metext"
검색에 표시되어야 합니다. 어떻게 해야 하나요?
답변1
최신 버전의 GNU grep
(옵션 포함 -z
)에서는 다음 한 줄을 사용할 수 있습니다.
find . -type f -exec grep -lz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' {} +
공백을 고려하면 단어 사이에만 올 수 있습니다.
현재 디렉토리에서 시작하여 모든 파일을 재귀적으로 검색하려면 가 필요하지 않고 (recursive) find
만 사용하면 됩니다 . 검색할 파일을 선택적으로 선택하는 데 사용할 수 있습니다(예: 제외할 디렉터리의 파일 선택). 간단히 말해서:grep -r
find
grep -rlz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' .
여기서 주요 요령은
-z
새 줄 대신 ASCII NUL로 끝나는 입력 스트림의 각 줄을 처리하므로 일반적인 방법을 사용하여 줄 바꿈을 일치시킬 수 있다는 것입니다.[[:space:]]
문자 클래스 패턴은 공백, 탭, CR, LF 등을 포함한 모든 공백 문자를 나타냅니다. 따라서 이를 사용하여 단어 사이에 들어갈 수 있는 모든 공백 문자를 일치시킬 수 있습니다.grep -l
원하는 패턴이 있는 파일 이름만 인쇄합니다. 일치 항목도 인쇄하려면-H
대신 을 사용하십시오-l
.
반면에 단어가 아닌 공백이 어느 위치에나 올 수 있다면 보기에 좋지 않습니다.
grep -rlz
't[[:space:]]*h[[:space:]]*i[[:space:]]*s[[:space:]]*i[[:space:]]*\
s[[:space:]]*s[[:space:]]*o[[:space:]]*m[[:space:]]*e[[:space:]]*\
t[[:space:]]*e[[:space:]]*x[[:space:]]*t' .
-P
(PCRE) 옵션을 사용하면 [[:space:]]
다음으로 대체할 수 있습니다 \s
(이것이 훨씬 더 멋져 보일 것입니다).
grep -rlzP 't\s*h\s*i\s*s\s*i\s*s\s*s\s*o\s*m\s*e\s*\
t\s*e\s*x\s*t' .
@steeldriver의 제안을 사용하여 sed
패턴을 생성하는 것이 최선의 선택이 될 것입니다.
grep -rlzP "$(sed 's/./\\s*&/2g' <<< "thisissometext")" .
답변2
모든 공백을 삭제하고 grep할 수 있습니다.
tr -d '[[:space:]]' < foo | grep thisissometext
확장:
find . -type f -exec bash -c 'for i; do tr -d "[[:space:]]" < "$i" | grep -q thisissometext && printf "%s\n" "$i"; done' _ {} +
확장된 명령 bash
은 다음과 같습니다.
for i
do
tr -d "[[:space:]]" < "$i" |
grep -q thisissometext &&
printf "%s\n" "$i"
done
이는 모든 인수를 반복하고 위의 테스트를 사용합니다.
답변3
아래 코드는 디렉토리에서 파일을 재귀적으로 검색하고 " "
및 항목을 모두 제거합니다 "\n"
. 문자열이 나머지 텍스트에 존재하면 일치하는 것입니다. 이는 공백/개행 문자가 켜질 수 있음을 의미합니다.어느파일 내부 문자열의 위치입니다.
기능
일치하는 파일을 찾으면 다음과 같은 경로를 포함하여 터미널에 인쇄됩니다.
/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt
읽을 수 없는 파일이 실행될 경우 스크립트가 중단되는 것을 방지하기 위해 내가 내장한 try / Except입니다.
스크립트
#!/usr/bin/env python3
import os
import sys
s = sys.argv[2]
for root, dirs, files in os.walk(sys.argv[1]):
for file in files:
file = root+"/"+file
try:
if s in open(file).read().replace(" ", "").replace("\n",""):
print(file)
except:
pass
사용하는 방법
- 스크립트를 빈 파일에 복사하고 다른 이름으로 저장하세요.
find_string.py
디렉터리와 문자열을 인수로 사용하여 실행합니다.
python3 /path/to/find_string.py <directory> <string_to_find>
문자열이나 디렉터리에 공백이 포함되어 있으면 따옴표를 사용하세요.
python3 /path/to/find_string.py '<directory>' '<string_to_find>'
메모
스크립트는 공백이나 개행 문자가 포함된 문자열이 있는 파일을 찾습니다. 다음 줄에 다른 문자/문자열(예: 탭)을 사용하여 확장할 수 있습니다.
if s in open(file).read().replace(" ", "").replace("\n",""):
답변4
개행 문자를 처리하는 데 사용할 수 grep -i --recursive 'word1\|word2' *
있고 사용할 수 있습니다.awk '/word1/,/word2/'