0

我有一个充满文件的目录,其中包含我要捕获的数字。我还想知道哪些数字来自哪些特定文件。现在我正在运行 grep,它会输出如下内容:

grep ./* -e 'expression'
./file1: expression numberA
./file1: expression numberB
./file1: expression numberA
./file2: expression numberC numberD
...

我想要的是提取一段文件名(在本例中,文件 1 为 1),以及出现在我的表达式之后的所有数字。

虽然我更喜欢在 bash 中做所有事情,但欢迎任何解决方案。

编辑:为了清楚起见,我想输出以下内容:

file1:
numberA
numberB
file2:
numberC
numberD
...

我还编辑了前面的部分(./file1: 表达式 numberA)。抱歉之前没有说清楚。

4

4 回答 4

1

尝试这个:

grep -e 'expression' * | perl -pe 's/^(.*?)(\d+)(:.*)$/$1$2$3 $2/'

这应该产生所有输入行。如果输入行的文件名部分以数字结尾,则该数字应附加到输入行。

$1,$2并且$3是对 3 个子表达式(括号中的正则表达式的那些部分)的反向引用。

命令行开关-e指示 Perl 解释器执行给定的表达式。-p循环输入并打印$_.

但是,由于您还想要比赛后的所有数字,您可能需要更复杂的东西:

grep -e 'expression' * | perl -ne '
  chomp;
  ($a,$b) = split ":";
  $a =~ s/.*(\d+)$/$1/;
  $b =~ s/.*expression(.*)/$1/;
  $b =~ s/[^\d]+/ /g;
  print "$_ $a $b\n";
'

-n与 相同-p,只是没有隐式打印$_

编辑:在阅读了您更新的要求后,我认为您最好使用全 Perl 解决方案。

#!/usr/bin/env perl

use strict;
use warnings;

foreach (@ARGV) {
  my $file = $_;
  open FILE, "<$file" or die "Can't open file $file.";
  my $first = 1;
  foreach (<FILE>) {
    if (m/expression(.*)/) {
      my $values = $1;
      if ($first) {
        print "$file:\n";
        $first = 0;
      }
      $values =~ s/(^ +| +$)//g;
      $values =~ s/ +/\n/g;
      print "$values\n";
    }
  }
  close FILE;
}
于 2013-04-14T21:57:48.313 回答
0

感谢回答的两位-根据你们俩给我的信息,我能够找到一个完美的解决方案:

grep -i expression ./* | perl -pe 's/.*(\d+).*:.*(\d+)/$1 $2/' | sort | uniq

这给出了输出:

1 numberA
1 numberB
2 numberC numberD
于 2013-04-16T15:57:33.747 回答
0

我认为在这种情况下不需要 grep 。需要用awk或perl来积累数据,这样就可以在文件中查找表达式了。这是一个 awk 示例:

awk '/expression/ {f[FILENAME]; for(i=2;i<=NF;++i) v[FILENAME,$i]} 
END {for(i in f) {print i":"; for(j in v) if(sub("^"i SUBSEP,"",j))print j}}' ./*

输出

file1:
numberB
numberA
file2:
numberD
numberC
于 2013-04-16T20:48:14.213 回答
0

如果您只想查看文件编号和编号,您可以使用以下内容:

find . -exec sh -c "echo -n \;{}::;grep -e 'expression' {}" \; | perl -pe 's/^.*(\d+)::/File \1:\n/' | perl -pe 's/\D*(\d+)$/\1/'

注意:如果您的表达式包含::number(用作分隔符,可以更改),这将中断。如果未找到匹配项,则打印最后一个文件名。

会产生:

File 2:
878
File 3:
199
File 4:
123
234
9
0

示例文件 2:

foo 123
bar 123
expression 878
lorem ipsum

如果您只想要数字对(文件号+数字),那么您可以尝试:

grep ./* -e 'expression' | perl -pe 's/^.*?(\d+):.*?(\d+)$/\1 \2/'

输出:

2 878
3 199
4 123
4 234
4 9
4 0

正如我在评论中提到的,您的问题对于您想要的内容有些不清楚。提供一些示例将是有益的。

于 2013-04-15T09:40:38.660 回答