我的目录中包含了我想要捕获的数字的文件。我还想知道哪些数字来自哪些特定文件。现在我只是运行grep,输出类似:
grep ./* -e 'expression'
./file1: expression numberA
./file1: expression numberB
./file1: expression numberA
./file2: expression numberC numberD
...
我想要的是提取一段文件名(在本例中,1代表file1),以及我表达后出现的所有数字。
虽然我更喜欢用bash做所有事情,但欢迎任何解决方案。
编辑:要清楚,我想要输出以下内容:
file1:
numberA
numberB
file2:
numberC
numberD
...
我还编辑了前面的部分(./file1:表达式编号A)。很抱歉以前不清楚。
答案 0 :(得分: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;
}
答案 1 :(得分: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
正如我的评论中提到的,你的问题在你想要的确切内容上有点不清楚。提供一些例子将是有益的。
答案 2 :(得分:0)
感谢两位回答的人 - 根据你们双方给我的信息,我能够找到一个完美的解决方案:
grep -i expression ./* | perl -pe 's/.*(\d+).*:.*(\d+)/$1 $2/' | sort | uniq
这给出了输出:
1 numberA
1 numberB
2 numberC numberD
答案 3 :(得分:0)
我认为在这种情况下不需要grep。需要awk或perl来累积数据,因此他们可以在文件中查找表达式。这是一个例子:
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