我的目标是仅在PATH与文件中的PATH匹配时才删除文件中的行
例如,我需要从/ tmp / file文件中删除所有包含/ etc / sysconfig PATH的行
more /tmp/file
/etc/sysconfig/network-scripts/ifcfg-lo file1
/etc/sysconfig/network-scripts/ifcfg-lo file2
/etc/sysconfig/network-scripts/ifcfg-lo file3
我编写了以下Perl代码(我的bash脚本中集成的perl代码),以删除具有“/ etc / sysconfig”的行
export FILE=/etc/sysconfig
perl -i -pe 's/\Q$ENV{FILE}\E// ' /tmp/file
但是在运行perl代码之后我得到以下内容:(到位得到空行)
/network-scripts/ifcfg-lo file1
/network-scripts/ifcfg-lo file2
/network-scripts/ifcfg-lo file3
第一个问题:
如何更改perl语法:perl -i -pe的/ \ Q $ ENV {FILE} \ E //'以删除与所需PATH(/ etc / sysconfig)匹配的行?
第二个问题:
与第一个问题相同,但只有当PATH与文件中的第一个字段匹配时,才会删除行
示例:
在perl编辑之前/ tmp / file:
file1 /etc/sysconfig/network-scripts/ifcfg-lo
/etc/sysconfig/network-scripts/ifcfg-lo file2
/etc/sysconfig/network-scripts/ifcfg-lo file3
perl编辑后的/ tmp / file:
file1 /etc/sysconfig/network-scripts/ifcfg-lo
答案 0 :(得分:3)
Perl是一个很好的方法。使用-n开关,而不是-p。
perl -i -l -n -e'print unless /\Q$ENV{FILE}/' filename
答案 1 :(得分:0)
s/pattern/otherpattern/
不会删除整行;它只会改变子串。您需要完全更改程序以删除整行。在伪代码中,它将是:
while (read in a line)
{
if (doesn't match)
{
write the line back out unaltered.
}
}
虽然知道continue
和redo
如何在循环中工作,但仍然可以重写为oneliner:perl -pe '$_ = <> and redo if /Q$ENV{FILE}\E/'
答案 2 :(得分:0)
mef@iwlappy:~$ cat /tmp/file
aaaa
/etc/sysconfig/network-scripts/ifcfg-lofile1
/etc/sysconfig/network-scripts/ifcfg-lofile2
/etc/sysconfig/network-scripts/ifcfg-lofile3
aaa
mef@iwlappy:~$ perl -i -pe 's/$ENV{FILE}\E.*//' /tmp/file
mef@iwlappy:~$ cat /tmp/file
aaaa
aaa
您可以使用s / ^ $ //
执行进一步的正则表达式以删除空行答案 3 :(得分:0)
如果我是从命令行执行此操作,我可能甚至不会使用Perl。我只是使用一个否定的grep:
$ mv old.txt old.bak; grep -v $FILE old.bak > old.txt
重命名原始文件并使用旧名称写入新文件与perl的-i
开关为您做的事情相同。
如果你只想匹配第一列,那么我可能会向perl倾斜,所以我不必使用awk或cut。 perl的-a
开关在空白处拆分行,并将结果放在@F
中:
$ perl -ai.bak -ne 'print if $F[0] !~ /^\Q$ENV{FILE}/' old.txt
当您认为自己正确时,可以删除保存原始文件副本的.bak
训练轮。或不。我倾向于喜欢安全网。
有关命令行开关的详细信息,请参阅perlrun。