我有一个控制文件 - 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 - 将按行号(第一个字段)按字典顺序对它们进行排序
猫 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,因为您从 1 开始 data.txt,而不是从 0 开始,否则就没有必要)。