Bashの1行で一致する単語の位置(文字の位置ではない)を見つける

Bashの1行で一致する単語の位置(文字の位置ではない)を見つける

私は次のような行を持っています

Xckt VDD VSS sig[1] sig[2] sig[3] sig[4] sig[5] sig[6] CKT

sig[4]がどこにあるのか探したいです。この場合は返却する必要があります。7。同じことをするために、Bashの単純なスクリプト/1行のスクリプトが必要です。重複一致の場合、すべての一致が行に発生するとシーケンス番号が大きくなります。

答え1

awk次のことができます。

awk '{for(i=1;i<=NF;i++)if($i=="sig[4]")print i}'

これは、複数の項目がある場合にも有効です。

すべての数字が同じ行にある必要がある場合は、に置き換えてprintそれprintfに応じて調整できます。

答え2

Rushには素晴らしいワンラインソリューションがあります。;これは、文字列のすべての一致を印刷する単純なbash関数です。

function pratappos() {
  target=$1; shift
  pos=1
  while [[ $# -gt 0 ]]
  do
    [[ "$1" = "$target" ]] && echo $pos
    shift; ((++pos))
  done
  unset target pos
}

指定されたリストから文字列を取得するように一般化されているため、たとえば、.bashrcまたは現在のシェルで関数を設定した後、次のように呼び出すことができます。

pratappos sig[4] Xckt VDD VSS sig[1] sig[2] sig[3] sig[4] sig[5] sig[6] CKT
7

または(両方のゲーム):

pratappos sig[4] Xckt VDD VSS sig[1] sig[2] sig[3] sig[4] sig[5] sig[6] CKT sig[4]
7
11

...渡された最初の引数は検索する文字列として扱われ、その後に検索する文字列の残りの部分が続きます。これはshift、指定された文字列を$ IFSで区切られたように処理する位置引数を使用します。

前のポイントを明確にするには、次のようにします。

pratappos 'foo bar' a b foo bar 'foo bar' rest here
5

答え3

perlたとえば、で説明されているように、List :: MoreUtilsモジュールを使用してこれを実行できます。[perl] 配列内の一致する項目のインデックスを取得します。

perl -MList::MoreUtils=indexes -alne '
  print $_+1 for indexes { $_ eq "sig[4]" } @F
'

与えられた入力ラインを使用してテスト

$ perl -MList::MoreUtils=indexes -alne '
  print $_+1 for indexes { $_ eq "sig[4]" } @F
' <<< "Xckt VDD VSS sig[1] sig[2] sig[3] sig[4] sig[5] sig[6] CKT"
7

行には複数のインスタンスが含まれています。

$ perl -MList::MoreUtils=indexes -alne '
  print $_+1 for indexes { $_ eq "sig[4]" } @F
' <<< "Xckt VDD VSS sig[1] sig[2] sig[3] sig[4] sig[5] sig[6] sig[4] CKT"
7
10

関連情報