一起使用grep和awk

dul*_*uli 10 bash awk grep

我有一个文件(A.txt),数字上有4列,另一个文件有3列数字(B.txt).我需要解决以下问题:

  1. 查找A.txt中的所有行,其第3列的编号显示在B.txt的第3列中的任何位置.

  2. 假设我在目录中有很多像A.txt这样的文件.我需要为该目录​​中的每个文件运行它.

我该怎么做呢?

Dav*_* W. 19

你永远不应该看到有人在一起使用grep,awk因为无论grep做什么,你也可以做awk:

Grep和Awk

grep "foo" file.txt | awk '{print $1}'
Run Code Online (Sandbox Code Playgroud)

仅使用Awk:

awk '/foo/ {print $1}' file.txt
Run Code Online (Sandbox Code Playgroud)

我不得不放弃我的胸膛.现在你的问题......

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;
}
Run Code Online (Sandbox Code Playgroud)


sli*_*nov 9

这是一个例子.创建以下文件并运行

awk -f c.awk B.txt A*.txt 
Run Code Online (Sandbox Code Playgroud)

c.awk

FNR==NR {
    s[$3]
    next
}

$3 in s {
    print FILENAME, $0
}
Run Code Online (Sandbox Code Playgroud)

A1.txt

1 2 3
1 2 6
1 2 5
Run Code Online (Sandbox Code Playgroud)

A2.txt

1 2 3
1 2 6
1 2 5
Run Code Online (Sandbox Code Playgroud)

B.txt

1 2 3
1 2 5
2 1 8
Run Code Online (Sandbox Code Playgroud)

输出应该是:

A1.txt 1 2 3
A1.txt 1 2 5
A2.txt 1 2 3
A2.txt 1 2 5
Run Code Online (Sandbox Code Playgroud)

  • 好的,我明白了.FNR仅适用于ORIGINAL文件.如果该行在`B.txt`中,你只会把东西放在`s`中.我认为下半场只有在你离开`B.txt`后才能执行. (2认同)