我有一个文件(A.txt),数字上有4列,另一个文件有3列数字(B.txt)。我需要解决以下问题:
查找A.txt中的所有行,其中第3列的数字显示在B.txt的第3列中的任何位置。
假设我在目录中有很多像A.txt这样的文件。我需要为该目录中的每个文件运行它。
我该怎么做?
答案 0 :(得分:16)
你永远不应该看到有人一起使用grep
和awk
,因为无论grep
可以做什么,你也可以在awk
中进行:
grep "foo" file.txt | awk '{print $1}'
awk '/foo/ {print $1}' file.txt
我不得不放弃我的胸膛。现在你的问题......
Awk是一种编程语言,它假定在一组文件中的所有行中都有一个循环。而且,你不想这样做。相反,您希望将B.txt
视为特殊文件并循环使用其他文件。这通常需要像Python或Perl这样的东西。 (BASH的旧版本没有处理散列键阵列,因此这些版本的BASH不起作用。)然而,slitvinov似乎找到了答案。
无论如何,这是一个Perl解决方案:
use strict;
use warnings;
use feature qw(say);
use autodie;
my $b_file = shift;
open my $b_fh, "<", $b_file;
#
# This tracks the values in "B"
#
my %valid_lines;
while ( my $line = <$b_file> ) {
chomp $line;
my @array = split /\s+/, $line;
$valid_lines{$array[2]} = 1; #Third column
}
close $b_file;
#
# This handles the rest of the files
#
while ( my $line = <> ) { # The rest of the files
chomp $line;
my @array = split /\s+/, $line;
next unless exists $valid_lines{$array[2]}; # Next unless field #3 was in b.txt too
say $line;
}
答案 1 :(得分:9)
这是一个例子。创建以下文件并运行
awk -f c.awk B.txt A*.txt
<强> c.awk 强>
FNR==NR {
s[$3]
next
}
$3 in s {
print FILENAME, $0
}
<强> A1.txt 强>
1 2 3
1 2 6
1 2 5
<强> A2.txt 强>
1 2 3
1 2 6
1 2 5
<强> B.txt 强>
1 2 3
1 2 5
2 1 8
输出应为:
A1.txt 1 2 3
A1.txt 1 2 5
A2.txt 1 2 3
A2.txt 1 2 5