**我的后续问题标有' * *'**
我被要求编写Perl代码,用{
替换每个{function(<counter>)
,并且在每次替换时,计数器应该大1。第一次替换{
将为{function(0)
,
{
的第二次替换将为{function(1)
等。
它假设在包含子文件夹的文件夹中的每个*.c
和*.h
文件中进行替换。
我写了这段代码:
#!/usr/bin/perl
use Tie::File;
use File::Find;
$counter = 0;
$flag = 1;
@directories_to_search = 'd:\testing perl';
@newString = '{ function('.$counter.')';
$refChar = "{";
finddepth(\&fileMode, @directories_to_search);
sub fileMode
{
my @files = <*[ch]>; # get all files ending in .c or .h
foreach $file (@files) # go through all the .c and .h flies in the directory
{
if (-f $file) # check if it is a file or dir
{
my @lines;
# copy each line from the text file to the string @lines and add a function call after every '{' '
tie @lines, 'Tie::File', $file or die "Can't read file: $!\n";
foreach ( @lines )
{
if (s/{/@newString/g)
{
$counter++;
@newString = '{function('.$counter.')';
}
untie @lines; # free @lines
}
}
}
}
代码搜索目录d:\testing Perl
并进行替换,但不是获取
{function(<number>)
我得到{function(number1) function(number3) function(number5) function(number7)
例如我获得的第一次替换
{function(0) function(2) function(4) function(6)
我希望获得{function(0)
我真的不知道我的代码有什么问题。
awk解决方案或任何其他Perl解决方案也将是伟大的!
* 我有一个跟进问题。 现在我希望我的perl程序在所有文件中进行相同的替换,除了行有'{'的行 和'}'在同一行。所以我用这种方式修改了代码。
#!/usr/bin/perl
use strict;
use warnings;
use Tie::File;
use File::Find;
my $dir = "C:/test dir";
# fill up our argument list with file names:
find(sub { if (-f && /\.[hc]$/) { push @ARGV, $File::Find::name } }, $dir);
$^I = ".bak"; # supply backup string to enable in-place edit
my $counter = 0;
# now process our files
#foreach $filename (@ARGV)
while (<>)
{
my @lines;
# copy each line from the text file to the string @lines and add a function call after every '{' '
tie @lines, 'Tie::File', $ARGV or die "Can't read file: $!\n";
#$_='{function(' . $counter++ . ')';
foreach (@lines)
{
if (!( index (@lines,'}')!= -1 )) # if there is a '}' in the same line don't add the macro
{
s/{/'{function(' . $counter++ . ')'/ge;
print;
}
}
untie @lines; # free @lines
}
我想要做的是遍历我在我的目录和子目录中找到的@ARGV中的所有文件以及每个* .c或* .h文件我想逐行查看是否这行包含'{'。如果确实存在,程序将不会检查是否存在“{”并且不会进行替换,如果不存在,则程序将使用'{function();'
替换'{'遗憾的是,此代码不起作用。 我很惭愧地说,我试图让它整天都工作,但仍然没有去。 我真的很感激一些帮助。
谢谢!!
答案 0 :(得分:3)
这是将查找方法与就地编辑相结合的简单方法。您可以使用Tie::File
,但它的结果确实相同。此外,不用说,在进行这样的编辑时,您应始终保留原始文件的备份,因为更改是不可逆转的。
因此,如果您不需要递归,那么您的任务在Unix / Linux风格中很简单:
perl -pi -we 's/{/"{ function(" . $i++ . ")"/ge' *.h *.c
当然,由于您似乎在使用Windows,cmd
shell不会对我们的参数进行全局化,因此我们需要手动执行此操作。我们需要改变报价。而且,我们需要为-i
(就地编辑)开关提供备份参数。
perl -pi.bak -we "BEGIN { @ARGV = map glob, @ARGV }; s/{/'{ function(' . $i++ . ')'/ge" *.h *.c
这几乎足以制作脚本。
如果确实需要递归,可以使用File::Find
。请注意,此代码的功能与上面的代码完全相同。
use strict;
use warnings;
use File::Find;
my $dir = "d:/testing perl"; # use forward slashes in paths
# fill up our argument list with file names:
find(sub { if (-f && /\.[hc]$/) { push @ARGV, $File::Find::name } }, $dir);
$^I = ".bak"; # supply backup string to enable in-place edit
my $counter = 0;
# now process our files
while (<>) {
s/{/'{ function(' . $counter++ . ')'/ge;
print;
}
不要被备份选项误导为错误的安全感:如果连续两次运行此脚本,那些备份将被覆盖,因此请记住这一点。
答案 1 :(得分:2)
$ perl -pi -e 's| (?<={) | q#function(# . ($i++) . q#)# |gex' *.c *.h
答案 2 :(得分:1)
使用awk '/{/{gsub(/{/,"{function("i++")");print;next}{print}'
和您的代码作为输入:
$ awk '/{/{gsub(/{/,"{function("i++")");print;next}{print}' file
sub fileMode
{function(0)
my @files = <*[ch]>; # get all files ending in .c or .h
foreach $file (@files) # go through all the .c and .h flies in the directory
{function(1)
if (-f $file) # check if it is a file or dir
{function(2)
my @lines;
# copy each line from the text file to the string @lines and add a function call after every '{function(3)' '
tie @lines, 'Tie::File', $file or die "Can't read file: $!\n";
foreach ( @lines )
{function(4)
if (s/{function(5)/@newString/g)
{function(6)
$counter++;
@newString = '{function(7)function('.$counter.')';
}
untie @lines; # free @lines
}
}
}
}
注意:对于嵌入式嵌套{
,函数编号不会递增。
$ echo -e '{ { \n{\n-\n{' | awk '/{/{gsub(/{/,"{function("i++")");print;next}1'
{function(0) {function(0)
{function(1)
-
{function(2)
说明:
/{/ # For any lines that contain {
gsub( /{/ , "{function("i++")" ) # replace { with function(i++)
print;next # print the line where the replacement happened and skip to the next
print # print all the lines
答案 3 :(得分:1)
可以在一行中完成,如下所示:
perl -pi -e 's/({)/"{function(".++$a.")"/ge;' your_file
我刚刚采用了一个示例输入文件并进行了测试。
> cat temp
line-1 { { { {
line-2 { { {
line-3 { {
line-4 {
现在执行:
> perl -pi -e 's/({)/"{function(".++$a.")"/ge;' temp
> cat temp
line-1 {function(1) {function(2) {function(3) {function(4)
line-2 {function(5) {function(6) {function(7)
line-3 {function(8) {function(9)
line-4 {function(10)