Linux Perl命令行多行替换

Linux Perl命令行多行替换,linux,perl,ubuntu,command-line,Linux,Perl,Ubuntu,Command Line,我正在尝试使用命令行perl替换多行文件中的文本。我正在使用Ubuntu Natty 下面是我的文本文件(称为test.txt)的内容: 下面是我的perl命令: perl -i -pe "s/(\[mysqld\][^\^]+)/\1\nsometext/g" test.txt 但是,我没有替换文件中的所有文本,而是以以下内容结束: [mysqld] sometext# # * Basic Settings # # # * IMPORTANT # If you make change

我正在尝试使用命令行perl替换多行文件中的文本。我正在使用Ubuntu Natty

下面是我的文本文件(称为test.txt)的内容:

下面是我的perl命令:

perl -i -pe "s/(\[mysqld\][^\^]+)/\1\nsometext/g" test.txt
但是,我没有替换文件中的所有文本,而是以以下内容结束:

[mysqld]

sometext#
# * Basic Settings
#

#
# * IMPORTANT
#   If you make changes to these settings and your system uses apparmor, you may
#   also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#

user            = mysql
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
skip-external-locking
#
我在RegexBuddy for Perl中尝试了正则表达式,它匹配文本文件中的所有内容,但由于某些原因,它在命令行中使用Perl时不起作用

我非常感谢你的帮助


提前感谢。

您正在逐行读取文件,因此只有第一行与您的正则表达式匹配。如果您真的想删除大部分内容,您需要做的是使用
-0
选项,例如
-0777
来清除文件。这是行结束处理,
777
只是一个按惯例用作八进制数的数字,它的大小足以导致文件阻塞

perl -0777 -i -pe 's/(\[mysqld\][^\^]+)/$1\nsometext/g' test.txt
此外,我还替换了你的报价。如果您使用*nix,那么单引号更可取。举个例子,
$1
不会被shell插入。

导致Perl迭代输入的每一行,并为每一行执行给定的代码(然后打印这些行)。具体来说,命令

perl -p -e 'SOME_CODE_HERE;'
与运行以下Perl程序完全相同:

LINE: while (<>) {
    SOME_CODE_HERE;
} continue {
    print or die "-p destination: $!\n";
}
行:while(){
这里有一些代码;
}继续{
打印或冲模“-p目标:$!\n”;
}
您的regexp似乎打算一次匹配多行,如果Perl逐行处理输入,这显然不起作用。要使其按预期工作,您(至少)有两个选项:

  • 通过使用。特别是,开关
    -0777
    使Perl将每个输入文件视为一行

  • 重写您的代码,例如使用


  • 顺便说一句,我强烈怀疑您的regexp并不是您认为的那个意思。特别是,
    [^\^]+
    匹配不包含插入符号(
    ^
    )的一个或多个字符组成的字符串。由于您的输入似乎不可能包含任何插入符号,因此这基本上相当于
    (?s:.+)
    (或者如果您使用的是
    +
    )。

    我不确定预期的结果应该是什么。@cornuz我认为从这个问题可以明显看出这一点。我说“不是替换文件中的所有文本,[以下]是我最终得到的…”这就很好地解释了这一点。从正则表达式来看,我想我需要的结果似乎很清楚。非常感谢。我不得不将其修改为:
    perl-0777-I-pe“s/(\[mysqld\][^\^]+)/\1\nsometext/g”test.txt
    ,因为我以后需要使用一些shell变量。干杯,干杯。你知道我怎么用单引号包含shell变量吗?!在双引号中,我会这样做:
    perl-0777-I-pe“s/(\[mysqld\][^^^^]+)/\1\n$var/g“test.txt
    ,如果知道如何使用单引号实现同样的功能,那就太好了?!再次感谢。@ChuckugWh您可以在一行中插入shell变量,是的。但如果您使用双引号,这意味着打算成为perl变量的变量也将被插值,因此会令人困惑。为什么不试试看:
    perl-lwe“print$var”
    谢谢。我会的。看起来双引号更适合我的具体情况,所以我现在会坚持使用双引号,直到我知道如何使用单引号。干杯。@chuckugwh:在命令行(一行)上将变量传递到Perl的环境中:
    perlvar=$shellvar Perl…'$ENV{“$perlvar”}…”
    或者您可以导出它(可能在单独的行上):
    export shellvar;perl…“$ENV{“shellvar”}…'
    。前者使它仅对单个子进程(可能还有它的子进程)的环境可用,而后者使它对任何子进程都可用。谢谢。正如你的回答所示,我对命令行并不完全精通,但我觉得它很有教育意义。干杯
    LINE: while (<>) {
        SOME_CODE_HERE;
    } continue {
        print or die "-p destination: $!\n";
    }