ファイル内の行番号とともに特定の単語が出てくる行を見つけて、行番号を配列に入れたいと思います。バッシュではどうしますか?

ファイル内の行番号とともに特定の単語が出てくる行を見つけて、行番号を配列に入れたいと思います。バッシュではどうしますか?

これは行番号を返しますが、文字列にあります。

grep -n -F -w $word $file | cut -d : -f 1

答え1

私はandのawk代わりにこれを使います。行番号を配列に入れるには、次のようにします。grepcutプロセスの交換とbashの組み込み(mapfilein bashの同義語はbashで実行するとbashよりも優れており、詳細なヘルプを得ることができます)。たとえば、mapfilereadarrayhelp mapfilehelp readarray

mapfile -t array < <(awk -v w="$word" '$0 ~ w {print NR}' "$file")

または、正規表現マッチングの代わりに固定文字列マッチングを使用します。

mapfile -t array < <(awk -v w="$word" 'index($0,w) {print NR}' "$file")

どちらも$wordawk のオプションを介して awk 変数にシェル変数を渡すので、含まれる文字列は何でも安全です。二重引用符で囲まれたawkスクリプトで$ wordを使用するよりもはるかに安全です。w-v

FNR注:入力ファイルが複数ある場合は、代わりに印刷できますNR。 NRは、これまで読んだすべての行の累積合計です。 FNRは行番号です。現在のファイルただ。 (私が「行」と言うとき、実際には「レコード」を意味します。なぜなら、awkは改行で区切られたレコードを含むプレーンテキストファイル以上を処理できるからです。)

答え2

bash行の内容を配列として読み取るには、次のものを使用できますreadarray -tmapfileマッピングそしていいえ文書zsh/mapfileこれにより、モジュールzshとその$mapfile特殊な連想配列(実際のマップファイル)との混乱が発生します。

readarray -t array < <(
  grep -nFwe "$word" -- "$file" | cut -d : -f 1
)

--(ところで、その周りにおよび/または引用符を拡張することを忘れました-e。)

あるいは、Split + glob演算子を使用することができ、すべてが数値であるため、glob無効をスキップできます。

IFS=$'\n'
array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )

これの利点は、パイプの終了状態が保存されることです。

zshでは、パラメータ拡張フラグを使用して、変更なしでfオンラインeedを分割できます。f$IFS

array=( ${(f)"$(grep -nFwe "$word" -- "$file" | cut -d : -f 1)" } )

ただし、ここではデフォルト値を使用することもできます(zshではこれを変更する$IFS理由はありません)。$IFS

array=( $(grep -nFwe "$word" -- "$file" | cut -d : -f 1) )

関連情報