这是我的问题: 我有两个文件,一个有名字(大约1k行,没有重复)
File_Names
A
C
F
第二个带有名称和数据的文件(大约100k行,没有重复)
File_Data
A
Data_A
B
Data_B
C
Data_C
D
Data_D
E
Data_E
F
Data_F
我需要从名称搜索到数据文件,打印结果和下一行。
类似的东西:
A
Data_A
C
Data_C
F
Data_F
我有找到数据文件名称的部分,但仍无法打印下一行
awk 'FNR==NR{
a[$1]++;
next}
a[$1]
' File_Names File_Data
返回
A
C
F
这是我所保留的代码的一部分,因为我已经尝试了其他代码,例如
awk 'FNR==NR{
a[$0]=FNR;i=FNR;next}
($0 in a){
t=$0;
getline;b[a[t]]=$0}
END{
for(k=1;k<=i;k++)print b[k]
}'
添加/删除行:
- {x=NR+1}(NR<=x){print}
- {getline;print;}
还尝试使用grep with
grep -f File_Names File_Data
但仍然没有。对不起重复的问题,但可用的解决方案对我不起作用。 提前谢谢。
答案 0 :(得分:6)
grep
解决方案:
grep -A1 --no-group-separator -xf File_Names File_Data
A num
- 在匹配行num
行尾随上下文
--no-group-separator
- 不要在行组之间打印分隔符输出:
A
Data_A
C
Data_C
F
Data_F
答案 1 :(得分:1)
这是一个简单的awk解决方案:
$ awk 'NR==FNR{a[$0]; next} $0 in a{print; getline; print}' File_Names File_Data
A
Data_A
C
Data_C
F
Data_F
这可能会限制内存中a
数组的大小,但我预计1000个密钥不会是一个大问题。它还有一个潜在的竞争,如果你有一行数据也是一个文件名,输出将是不稳定的。您可以通过确保仅在File_Data
中的奇数行上检查文件名来保护它:
$ awk 'NR==FNR{a[$0]; next} FNR%2 && $0 in a{print; getline; print}' File_Names File_Data
请注意,你可以单独使用bash做同样的事情,而不依赖于awk,尽管它几乎不会表现得很好:
$ declare -A FN; while IFS= read -r x; do FN[$x]=1; done < File_Names
$ while IFS= read -r x; do IFS= read -r y; [[ -n "${FN[$x]}" ]] && printf '%s\n%s\n' "$x" "$y"; done < File_Data
A
Data_A
C
Data_C
F
Data_F
这取决于declare -A
(关联数组)的bash版本4或更高版本。第一个循环使用文件名填充$FN
数组的键,第二个循环逐步检查密钥是否存在,如果找到密钥则打印结果。