큰 텍스트 파일에서 문자열의 여러 위치 찾기

큰 텍스트 파일에서 문자열의 여러 위치 찾기

특정 문자열의 텍스트에서 정확한 위치를 찾아야 합니다. 즉, 파일:

to be or not to be, that's the question

문자열 "to". 원하는 출력: 0,14(처음부터 찌르는 문자를 찾는 문자까지). 나는 시도했다:

$ grep -o 'to' myfile.txt | wc -l

이것은 나에게 "8597"을 제공합니다....그것이 전체 숫자라고 가정하지만 텍스트(문자)의 위치가 필요합니다.

답변1

$ awk -v str='to' '{ off=0; while (pos=index(substr($0,off+1),str)) { printf("%d: %d\n", NR, pos+off); off+=length(str)+pos } }' file
1: 1
1: 14

또는 더 예쁜 형식은 다음과 같습니다.

awk -v str='to' '
    {
        off = 0  # current offset in the line from whence we are searching
        while (pos = index(substr($0, off + 1), str)) {
            # pos is the position within the substring where the string was found
            printf("%d: %d\n", NR, pos + off)
            off += length(str) + pos
        }
    }' file

프로그램은 awk줄 번호와 그 줄의 문자열 위치를 출력합니다. 문자열이 한 줄에 여러 번 나타나면 여러 줄의 출력이 생성됩니다.

프로그램은 이 index()함수를 사용하여 행에서 문자열을 찾고, 발견되면 문자열이 발견된 행의 위치를 ​​인쇄합니다. 그런 다음 substr()문자열의 인스턴스가 더 이상 발견되지 않을 때까지 나머지 줄에 대해 (함수를 사용하여) 프로세스를 반복합니다 .

코드에서 이 off변수는 다음 검색을 수행해야 하는 줄 시작 부분의 오프셋을 추적합니다. 이 변수 에는 문자열이 발견된 부분 문자열 내의 pso오프셋이 포함되어 있습니다.off

이 문자열은 를 사용하여 명령줄에 전달됩니다 -v str='to'.

예:

$ cat file
To be, or not to be: that is the question:
Whether ‘tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them? To die: to sleep;
No more; and by a sleep to say we end
The heart-ache and the thousand natural shocks
That flesh is heir to, ‘tis a consummation
Devoutly to be wish’d. To die, to sleep;

$ awk -v str='the' '{ off=0; while (pos=index(substr($0,off+1), str)) { printf("%d: %d\n", NR, pos+off); off+=length(str)+pos} }' file
1: 30
2: 4
2: 26
5: 21
7: 20

답변2

노력하다

grep -b 'to' file

파일 시작 부분의 오프셋입니다.

grep -nb 'to' file

줄 번호 및 오프셋에 사용됩니다.

답변3

파일에 여러 줄이 있고 처음 나타나는 문자열을 찾으려면 다음을 사용할 수 있습니다.

sed -zE 's/^(\w[^to]+)(to)(.*)/\1\2/' YourFile | wc -c

답변4

grep이를 수행하려면 다음 방법을 사용할 수 있습니다 .

$ grep -aob 'to' file | grep -oE '[0-9]+'
0
13

그런데, 0,14를 찾고 있다고 말하면 수학이 잘못되었습니다. to0을 첫 번째로 계산하면 두 번째는 위치 13에서 시작하는 반면 좌표는 0에서 시작하는 것처럼 보입니다.

위의 출력을 쉼표로 구분된 좌표 목록으로 만들려면 다음을 수행하세요.

$ grep -aob 'to' file | grep -oE '[0-9]+' | paste -s -d ','
0,13

어떻게 작동하나요?

grep이 방법은 일치하는 바이트 오프셋( )을 인쇄하는 GNU의 기능을 활용 하고 스위치를 통해서만 이를 인쇄 -b하도록 강제합니다 .-o

   -b, --byte-offset
          Print the 0-based byte offset within the input file before each
          line of output.  If -o (--only-matching) is specified, print the 
          offset of the matching part itself.

고급 예

예제에 toto여러 줄 또는 같은 단어가 포함된 경우 위 방법의 향상된 버전을 사용하면 해당 단어도 처리할 수 있습니다.

견본
$ cat file
to be or not to be, that's the question
that is the to to question
toto is a dog
$ grep -aob '\bto\b' file | grep -oE '[0-9]+' | paste -s -d ','
0,13,52,55

\b여기서는 계산하려는 단어의 양쪽에 단어 경계를 사용하여 와 to같은 단어가 아닌 문자열의 명시적인 발생만 계산합니다 toto.

인용하다

관련 정보