특정 문자열의 텍스트에서 정확한 위치를 찾아야 합니다. 즉, 파일:
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를 찾고 있다고 말하면 수학이 잘못되었습니다. to
0을 첫 번째로 계산하면 두 번째는 위치 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
.