从控制文件中读取数字并从数据文件中提取匹配的行号

从控制文件中读取数字并从数据文件中提取匹配的行号

我有一个控制文件 - 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 开始,否则就没有必要)。

相关内容