2番目のリストでリスト要素の最初の項目を見つけるBashスクリプト

2番目のリストでリスト要素の最初の項目を見つけるBashスクリプト

val_str="11 22 33"必要に応じて配列として保存できる数値のリスト(重複なし)がありますval_arr=(11 22 33)。たとえば、次のようになります。

タブ区切りファイルのフィールドから取得した2番目の数値のリストがあります。必要に応じて使用できますawk。以下はおもちゃのデータです。

echo -e "66\n55\n99\n33\n11\n88\n77\n22\n33" > list

val_arrに表示される最初の要素の値を見つけたいですlist。の一部の要素val_arrはに表示されない場合がありますlist。以下のコードは、 のすべての要素val_arrが にある場合は動作しますが、listそうでない場合は失敗します (例: if ) val_arr=(11 44 22 33)

val_arr=(11 22 33)
echo -e "66\n55\n99\n33\n11\n88\n77\n22\n33" > list
pos_arr=()
for i in ${!val_arr[@]}; do
    list_pos=$(grep -nm 1 ${val_arr[$i]} list | cut -f1 -d:)
    pos_arr+=( ${list_pos} )
done

pos1=$(echo ${pos_arr[@]} | tr ' ' '\n' | awk 'NR==1 {min=$0} NR>1 && $1<min {min=$1; pos=NR} END {print pos}')
pos0=$(( pos1 - 1 ))
val=${val_arr[$pos0]}

どちらの場合も、スクリプトval_arr=(11 22 33)が 。val_arr=(11 44 22 33)33

私の質問は次のとおりです

  1. もっと良い方法がありますか?
  2. このコードを欠けている値に対して強くする方法はありますか(val_arryすべての値をwithの末尾に追加するよりもエレガントです)。listecho ${pos_arr[@]} | tr ' ' '\n' >> list

ありがとうございます!

awkPS上記のコードを提供した@ Adrian Frühwirthに感謝します。https://stackoverflow.com/questions/16610162/bash-return-position-of-the-smallest-entry-in-an-array

答え1

val_arrgrepパターンや式のリストに置き換えるのはどうですか?

$ echo "${val_arr[@]/#/-e}"
-e11 -e44 -e22 -e33

自分で使うの?

$ grep -wFm1 "${val_arr[@]/#/-e}" list
33

答え2

私はgrep配列を使用して文字列に変換します。

#!/bin/bash
val_arr=(11 22 33)

grep_string=$(tr ' ' '|' <<<"${val_arr[@]}")

first_found=$(grep -wEm1 "$grep_string" list);
if [[ -z $first_found ]]; then
  echo "None of the numbers were found"
else
  echo "Found: $first_found"
fi

このtrコマンドは、配列を次に区切られた要素のリストに変換します|

$ grep_string=$(tr ' ' '|' <<<"${val_arr[@]}")
$ echo $grep_string 
11|22|33

その後、grep -E使用されるオプションは次のとおりです。

  • -E|:「OR」を表すために使用できるように拡張正規表現を有効にします。
  • -w:単語全体が一致するため、3一致しません33-x入力に応じて(全行一致)を使用することもできます。
  • -m1:最初のゲームの後に停止します。

ファイルの場所も必要な場合は、-n行番号も印刷するように追加してください。

関連情報