制御ファイル 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 内の行をループし、そこから指定されたインデックスの配列要素を出力します (data.txt は 0 ではなく 1 から始まるため、マイナス 1 になります。そうでなければ不要です)。