大きなテキストファイル内の文字列の複数の場所を見つける

大きなテキストファイル内の文字列の複数の場所を見つける

特定の文字列のテキスト内の正確な位置を見つける必要があります。つまり、ファイル:

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

おすすめ記事