fgrep
마침표 및 기타 메타 문자가 포함된 리터럴 단어 검색을 처리하는 기능을 사용하고 싶지만 grep
해당 단어가 줄의 시작 부분에 있는지 확인해야 합니다.
예를 들어, 내가 원하는 것과 정확히 일치하지만 내가 원하지 않는 것과 도 fgrep 'miss.'
일치합니다 .miss.
admiss.
co. miss.
예를 들어 메타 문자를 이스케이프 처리할 수는 있지만 grep '^miss\.'
소스가 너무 커서 확실히 뭔가를 놓친 다음 다시 실행해야 합니다(밤새도록 소요됩니다). 예를 들어 어떤 경우에는 \1
이스케이프 코드가 "메타 의미"를 갖는 코드입니다.
이 문제를 해결할 방법이 있나요?
답변1
GNU의 경우 grep
PCRE 지원을 사용하여 빌드하고 $string
이것이 포함되어 있지 않다고 가정하면 \E
다음을 수행할 수 있습니다.
grep -P "^\Q$string"
perl
와 함께rindex
:
perl -sne 'print if rindex($_, $string, 0) == 0' -- -string="$string"
그리고 awk
:
S=$string awk 'index($0, ENVIRON["S"]) == 1'
답변2
데이터가 매우 큰 경우 grep
awk와 같은 보다 유연한 도구보다 빠를 수 있습니다. 내가 해야 할 일은 문자에 있는 특수 문자를 인용하고 전화하는 것뿐입니다 grep
.
pattern=$(printf '%s\n' "$literal_text" | sed 's/[\[.*^$]/\\&/g')
grep "^$pattern" my-big-file
텍스트에 ASCII 문자만 포함된 경우 grep이 바이트만 고려하도록 문자 세트를 C로 설정합니다. 일부 구현(예: 다양한 GNU grep 버전)에서는 멀티바이트 문자로 인해 속도가 크게 저하될 수 있습니다.
LC_CTYPE=C grep "^$pattern" my-big-file
정확한 전체 줄을 검색하려면 다음 옵션이 있습니다 grep -Fx -e "$literal_text"
. 그러나 이는 지정된 텍스트로만 구성된 줄만 일치하며, 지정된 텍스트로 시작하는 줄을 일치시키는 비슷한 방법은 없습니다.
답변3
그리고awk
awk -vword='miss.' 'index($0, word) == 1' file
여러 단어에 대해
awk 'BEGIN{for (i=2; i<ARGC; ++i)word[++j]=ARGV[i]; ARGC=2}
{for (i=1; i<=j; ++i)if (index($0, word[i]) == 1){print; continue}}' file \
word1 word2 word3
python
나도 이거 좋아해
python3 -c 'import sys
words = tuple(sys.argv[1:])
for line in sys.stdin:
print(line if line.startswith(words) else "", end="")
' <file word1 word2 word3
답변4
패턴이 많지 않은 경우:
perl -ne 'BEGIN {$exp = quotemeta("miss.")} print if /^$exp/'
나는 이것을 효율적으로 확장하는 방법을 모릅니다 grep -f
(파일에서 패턴을 읽는 것, 처리할 패턴이 많은 경우 수행할 작업).이 답변조인 쿼리가 흥미로운 것 같습니다.