制御ファイルから番号を読み取り、データファイルから一致する行番号を抽出します。

制御ファイルから番号を読み取り、データファイルから一致する行番号を抽出します。

制御ファイル(cntl.txt)があります。

2
3
5

データファイル-data.txt

red
blue
yellow
green
violet
orange

制御ファイルから一致する行を読み取る必要があります。ここで予想される出力は次のとおりです。

blue
yellow 
violet

答え1

非常に非効率的なソリューションの例:

for i in $(<control.txt); do awk -v c=$i 'NR~c{ print $0 }' data.txt; done;

また、今夜学んだ良い解決策を報告します。

awk 'FNR==NR{ z[$0]++;next }; FNR in z' control.txt data.txt

答え2

のみ使用POSIXの指定Sedの特徴:

sed -n -e "$(sed '/./s/$/p/' cntl.txt)" data.txt

もちろん、cntl.txtファイルに数字以外の行があると、エラーが発生する可能性があります。ただし、空行があると正しく処理されます(つまり、出力には影響しません)。

答え3

この試み:

join <(nl data.txt|sort -k1b,1) <(cat cntl.txt|sort -k1b,1) | sort -nk1,1 | cut -d' ' -f2-

nl - 行を列挙します。

 1  red
 2  blue
 3  yellow
 4  green
 5  violet
 6  orange

| sort -k1b,1 - 行番号(最初のフィールド)に基づいてアルファベット順にソートします。

cat cntl.txt | sort -k1b,1 - 制御ファイルを同じ順序でソートします。

2
3
5

Join <()<() - ソートされた(そして番号付き)「データ」を最初のフィールド(つまり行番号)のソートされた「コントロール」と結合します。

2 blue
3 yellow
5 violet

| sort -nk1,1 - 結果を数値に並べ替えます(行の並べ替え)。

| cut -d'' -f2- - 行番号フィールドを削除します。

blue
yellow
violet

答え4

別の考えられる解決策:

IFS=$'\n' read -d '' -r -a colors < 'data.txt'; unset IFS;

for i in $(<cntl.txt); do
        echo ${colors[i-1]} 
done

IFS 行は内部ファイル区切り文字を改行に設定し、data.txt の各行を配列に挿入します。次に、cntl.txtの行を繰り返し、指定されたインデックスを持つ配列要素を印刷します(ゼロではなく1からdata.txtを開始するため、マイナス1です。そうでなければ必要ありません)。

関連情報