Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 将一个文件搜索到另一个文件,打印匹配项和下一行_Bash_Awk_Grep - Fatal编程技术网

Bash 将一个文件搜索到另一个文件,打印匹配项和下一行

Bash 将一个文件搜索到另一个文件,打印匹配项和下一行,bash,awk,grep,Bash,Awk,Grep,这是我的问题: 我有两个文件,其中一个文件名约为1k行,没有重复 文件名 A C F 第二个文件的名称和数据约为100k行,没有重复 文件数据 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]++;

这是我的问题: 我有两个文件,其中一个文件名约为1k行,没有重复

文件名

A
C
F
第二个文件的名称和数据约为100k行,没有重复

文件数据

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]
}'
但还是什么都没有。很抱歉重复这个问题,但可用的解决方案对我不起作用。 提前感谢。

grep解决方案:

grep -A1 --no-group-separator -xf File_Names File_Data
$ 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
num-在匹配行之后打印尾随上下文的num行 -无组分隔符-不要在行组之间打印分隔符 输出:

A
Data_A
C
Data_C
F
Data_F
grep解决方案:

grep -A1 --no-group-separator -xf File_Names File_Data
$ 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
num-在匹配行之后打印尾随上下文的num行 -无组分隔符-不要在行组之间打印分隔符 输出:

A
Data_A
C
Data_C
F
Data_F

以下是一个简单的awk解决方案:

grep -A1 --no-group-separator -xf File_Names File_Data
$ 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
这可能会限制内存中数组的大小,尽管我预计1000个键不会是一个大问题。它也有一个潜在的竞争,如果你有一行数据也是一个文件名,输出将是不稳定的。您可以通过确保仅在文件\u数据中的奇数行上检查文件名来防止出现这种情况:

请注意,您可以单独在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数组的键,第二个循环检查键是否存在,如果找到键,则打印结果。

下面是一个简单的awk解决方案:

grep -A1 --no-group-separator -xf File_Names File_Data
$ 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
这可能会限制内存中数组的大小,尽管我预计1000个键不会是一个大问题。它也有一个潜在的竞争,如果你有一行数据也是一个文件名,输出将是不稳定的。您可以通过确保仅在文件\u数据中的奇数行上检查文件名来防止出现这种情况:

请注意,您可以单独在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数组的键,第二个循环检查键是否存在,如果找到键,则打印结果。

我无法想象任何解决方案会比这更快。虽然我可能会选择-F而不是-W,因为文件名很可能是固定字符串,而不是regexps.thx。文件名在每行后面都有一个\t,这就是所有操作失败的原因。我用sed删除了它,这个grep工作得很好。我无法想象任何解决方案会比这个更快。虽然我可能会选择-F而不是-W,因为文件名很可能是固定字符串,而不是regexps.thx。文件名在每行后面都有一个\t,这就是所有操作失败的原因。我用sed删除了它,这个grep工作得很好。我很好奇为什么你的grep解决方案不起作用。您是否在MS Windows上生成了一个或两个文件?如果文件数据文件是在unix中生成的,则行末尾的不可见CR字符可能会导致文件名行不匹配。奇怪的是,为什么您的grep解决方案不起作用。您是否在MS Windows上生成了一个或两个文件?如果文件\u数据文件是在unix中生成的,则行末尾的不可见CR字符可能会导致文件\u名称行不匹配。使用bash,您可以使用mapfile-t FN