我有一个包含以下行的(BIG)文件:
foobar {} foo{} bar{} foobar{}{}
foo {} foodfg{} bar{} foogfdbar{}
line without brackets
foobdgar {} fdfgoo{} bga foodfbar{}{}
fdfgoobar {} fdfoo dbar{} fooddbar
现在我想分别用{$ MATCH_COUNT} 替换每一行<}>
意思是输出应该如下所示:
foobar {0} foo{1} bar{2} foobar{3}{4}
foo {0} foodfg{1} bar{2} foogfdbar{3}
line without brackets
foobdgar {0} fdfgoo{1} bga foodfbar{2}{3}
fdfgoobar {0} fdfoo dbar{1} fooddbar
我怎样才能在perl或awk中执行此操作?我不是这些语言的专家,所以如果你能很快解释代码的作用,我将非常感激。
到目前为止我的解决方案不能像我预期的那样工作:
Perl:
cat test.properties | perl -e 'while(<>){ $c=0; while(/{}/g){print "{$c}"; $c++} print "\n"}'
(替换它就像我想要但不保留不匹配的东西)
Awk:
cat test.properties | awk '{ print "{" gsub(/{}/, "") "}" }'
(用完整的计数替换每一行 - 不是我想要的)
答案 0 :(得分:6)
这里需要的是模式替换的reviews: @branch.reviews
标志。这说'评估&#39;并允许您在正则表达式替换中使用代码表达式。比如e
例如:)
E.g:
$count++
似乎做你想做的事。
简化这一点:
#!/usr/bin/env perl
use strict;
use warnings;
while ( <DATA> ) {
my $count = 0;
s/{}/"{".$count++."}"/ge;
print
}
__DATA__
foobar {} foo{} bar{} foobar{}{}
foo {} foodfg{} bar{} foogfdbar{}
line without brackets
foobdgar {} fdfgoo{} bga foodfbar{}{}
fdfgoobar {} fdfoo dbar{} fooddbar
请注意perl的perl -pe '$c=0; s/{}/"{".$c++."}"/ge' text.properties
标记 - 它将您的代码包装在一个循环中,这样它的工作方式很像“sed&#39;会(例如-p
和while ( <> ) {
每行(你去),这是你在手中的例子中所做的事情。#39;
如果您愿意,也可以使用print
标志进行就地编辑。
我还要注意 - -i
或cat | awk
是多余的 - 在执行时都会获取文件参数。
答案 1 :(得分:2)
FS =字段分隔符。
NF =已拆分线的字段数。
&#39; printf的&#39;就像C-Standard功能一样。
cat test.properties | awk 'BEGIN{ FS="{}" }{ for(i=1;i<NF;++i) { printf "%s{%i}", $i, i-1; } printf "\n"; }'
答案 2 :(得分:1)
在awk中:
$ awk '{i=0; while(sub(/{}/,"{" i++ "}"));}1' file
foobar {0} foo{1} bar{2} foobar{3}{4}
foo {0} foodfg{1} bar{2} foogfdbar{3}
line without brackets
foobdgar {0} fdfgoo{1} bga foodfbar{2}{3}
fdfgoobar {0} fdfoo dbar{1} fooddbar
说明:
{
i=0 # initialize i to 0
while(sub(/{}/,"{" i++ "}")); # while replacing with increasing i do nothing else
} 1 # implicit print