Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.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 在文本b中查找文本a中的所有值,并在其旁边键入其他文件中的其他列(使用awk)_Bash_Shell_Sed_Awk_Statistics - Fatal编程技术网

Bash 在文本b中查找文本a中的所有值,并在其旁边键入其他文件中的其他列(使用awk)

Bash 在文本b中查找文本a中的所有值,并在其旁边键入其他文件中的其他列(使用awk),bash,shell,sed,awk,statistics,Bash,Shell,Sed,Awk,Statistics,a、 文本 b、 文本 现在是b.txt中的第二列值,我想知道它们是否存在于a.txt中,如果存在,我们在b.txt中的第二列(或其他文件)旁边写入a.txt中的第一列,以获得这样的文件,如: 1,a 2,b 3,c 4,d .....(etc) 21,u 22,v 23,w 24,x 25,y 26,z 27,xono a 28,a yuli x 29,p dao 30,... 31,abc 32,def 33,ghi 34,jkl 35,mno 36,pqr 我知道你要的是awk,是的,这

a、 文本

b、 文本

现在是b.txt中的第二列值,我想知道它们是否存在于a.txt中,如果存在,我们在b.txt中的第二列(或其他文件)旁边写入a.txt中的第一列,以获得这样的文件,如:

1,a
2,b
3,c
4,d
.....(etc)
21,u
22,v
23,w
24,x
25,y
26,z
27,xono a
28,a yuli x
29,p dao
30,...
31,abc
32,def
33,ghi
34,jkl
35,mno
36,pqr

我知道你要的是
awk
,是的,这是可能的。也许您可以在
perl
中基于此实现自己编写:

1,a
2,b
3,c,xd
4,d
.....(etc)
16,p
.....(etc)
21,u,xb,xd,xe,xf
22,v,xb,xe
23,w,xc,xe
24,x,xc
25,y,xa,xe
26,z,xa,xe,xf
27,xono a,xa
28,a yuli x,xd
29,p dao,xf
30,...
31,abc,xa
32,def,xb
33,ghi,xc
34,jkl,xd
35,mno,xe
36,pqr,xf
#/usr/bin/perl
严格使用;
我的%映射;
打开(my$a,'a.txt');
而(){
咀嚼;
我的($xx,@字母)=拆分(/,/);
每封我的$letter(@letters){
如果(!exists($mapping{$letter})){
$mapping{$letter}=[];
}
push(@{$mapping{$letter}},$xx);
}
}
打开(my$b,'b.txt');
而(){
咀嚼;
我的($num,$letter)=拆分(/,/);
if(存在($mapping{$letter})){
打印联接(“,”,$,@{$mapping{$letter}),“\n”;
}否则{
打印美元“\n”;
}
}
BASH/awk解决方案:

#!/usr/bin/perl

use strict;

my %mapping;

open(my $a, 'a.txt');
while (<$a>) {
    chomp;
    my ($xx, @letters) = split(/,/);
    foreach my $letter (@letters) {
        if (!exists($mapping{$letter})) {
            $mapping{$letter} = [];
        }
        push(@{$mapping{$letter}}, $xx);
    }
}

open(my $b, 'b.txt');
while (<$b>) {
    chomp;
    my ($num, $letter) = split(/,/);
    if (exists($mapping{$letter})) {
        print join(',', $_, @{$mapping{$letter}}), "\n";
    } else {
        print $_, "\n";
    }
}
IFS=,&&whileread-rpq;开始执行awk-vp=“$p”-vq=“,$q”-F{
printf“%s%s”,p,q;gsub(/\./,“\\.”,q);r=q(,|$)}
$0~r{printf',%s',$1;next}END{print”“}a.txt;完成
这可能适合您(GNU-sed):


这将从
a.txt
构建一个sed脚本,该脚本针对
b.txt

运行。在
gawk
4.1版中,您可以使用数组数组。试一试

sed -r 's|^([^,]+)(,[^,]+)|/^[^,]+\2,?/s/$/,\1/\n\1|;/,/P;D' a.txt|sed -rf - b.txt
其中
s.awk
为:

gawk -F, -f s.awk a.txt b.txt 
NR==FNR{

对于(i=2;我看一看
manjoin
当然。虽然循环使用
IFS=,
b.txt
中的每个值使用到shell变量
p和q
。然后
p和q
作为参数传递给awk。awk然后使用
、a
、b
等搜索
a.txt中的每一行,如果找到了这些值打印。
print
在BEGIN/END中的语句用于打印参数和新行。
printf在BEGIN
中用于打印
“1,a”,“2,b”,“26,z”
等,第二个printf用于打印
”,v“”,xb“”,xe“
等。而
awk-v p=“$p”-v q=“,$q”
是awk将shell变量传递给awk的一种方式。是的:D你真是个伟人!非常感谢!那么你添加了~r?是为了什么呢?
$0~r
实际上是正则表达式匹配,因为我创建了
var r
as
,p(,|$)
这意味着
,p
后面跟逗号或行尾。是的,我见过该解决方案,但因为它需要awk 4+版本,我无法在本地测试它,因为我的awk在OSX上,这不是4+我喜欢该解决方案,但它与重复字符串u、v、w、x、y、z:21、uxd 22、vxb 23、wxc 24、xxc 25、yxa的显示内容不匹配它应该显示:21,u,xb,xd,xe,xf 22,v,xb,xe 23,w,xc,xe 24,x,xc 25,y,xa,xe,xe 26,z,xa,xe,xf清晰且简单且令人惊奇!谢谢!对键的解释和打印$0键?我们每次找到正确的字符串时都会连接值?我已经用awk尝试过了(不是gawk)它也能工作。这正常吗?最后一个问题:-F-F是为了什么???@user3057111我确信我已经安装了Gnu Awk版本3.1.8和版本4.1.0。它不适用于verson 3.1。如果键入
Awk--version
,你会得到什么?@user3057111它不是
-F-F
。它是
-F,
,首先是带set的将字段分隔符设置为
,然后
-f s.awk
告诉awk从文件
s.awk
读取脚本。
sed -r 's|^([^,]+)(,[^,]+)|/^[^,]+\2,?/s/$/,\1/\n\1|;/,/P;D' a.txt|sed -rf - b.txt
gawk -F, -f s.awk a.txt b.txt 
NR==FNR {
    for (i=2; i<=NF; i++)
        a[$i][$1]++
    next
}

{
    keys=""
    if ($2 in a) {
        for (i in a[$2])
            keys= keys","i
    }
    print $0 keys
}