特定の文字列のテキスト内の正確な位置を見つける必要があります。つまり、ファイル:
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
行番号とその行の文字列位置を出力します。文字列が1行に複数回表示されると、複数行の出力が生成されます。
プログラムはこの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を最初に計算すると、2番目は位置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
。