ファイル内のいくつかの文字列を探しており、UNIX コマンドを使用して正確な位置 (行番号と行内の位置) が必要です。
grep -nを使用して行番号を見つけることしかできませんが、出現数やその位置さえも取得できません。
これらすべてを行うためにgregexpr関数を使用して R でスクリプトを作成する方法は知っていますが、UNIX コマンドのみを使用したいと考えています。それに相当するものはありますか?
$ cat file
now is
the winter of our
discontent
$ awk 's=index($0,"winter") { print "line=" NR, "start position=" s}' file
line=2 start position=5
文字列のすべての出現箇所を検索したい場合:
$ cat file
now is
the winter (yes, winter) of our
discontent
$ cat tst.awk
BEGIN{ SLENGTH = length(string) }
{
skipped = 0
starts = ""
while ( SSTART = index($0,string) ) {
starts = starts (starts?" ":"") (skipped + SSTART)
$0 = substr($0,SSTART + SLENGTH)
skipped += (SSTART + SLENGTH - 1)
}
}
starts { print "line=" NR, "start position(s)=" starts }
$ awk -v string="winter" -f tst.awk file
line=2 start position(s)=5 18
通常、すべて大文字の変数名を使用することはお勧めしません。これらは通常、組み込み変数を示すためです。ただし、この場合は、文字列の index() (ユーザー提供の SSTART/SLENGTH) と正規表現の match() (組み込みの RSTART/RLENGTH)。
IMHO SSTART/SLENGTH は index() 関数に組み込まれているはずですが、なぜそれらがそうでなかったのか (match() の RLENGTH とは異なり、機能的に不要であり、パフォーマンスへの不必要な影響) を理解しています。それはnbdです。これは、 index() 関数 (names sidx()
) を定義および使用して、誰かが気にかけている/好む場合に実行するバージョンです。
$ cat tst.awk
function sidx(src,tgt) {
SLENGTH = ( (SSTART=index(src,tgt)) ? length(tgt) : 0 )
return SSTART
}
{
skipped = 0
starts = ""
while ( sidx($0,string) ) {
starts = starts (starts?" ":"") skipped + SSTART
$0 = substr($0,SSTART + SLENGTH)
skipped += SSTART + SLENGTH - 1
}
}
starts { print "line=" NR, "start position(s)=" starts }
$
$ awk -v string="winter" -f tst.awk file
line=2 start position(s)=5 18
警告: 検索する文字列として空の文字列を渡すと、上記のスクリプトは無限ループに入ります。必要に応じて、BEGIN セクションにそのテストを追加できます。
別のものが必要な場合は、サンプル入力と予想される出力で質問を更新し、要件を明確にしてください。