Perl 使用命令行删除文本?
我有一个巨大的文件,其中包含以下格式的行:Perl 使用命令行删除文本?,perl,shell,text,command-line,Perl,Shell,Text,Command Line,我有一个巨大的文件,其中包含以下格式的行: New-England-Center-For-Children-L0000392290 Southboro-Housing-Authority-L0000392464 Crew-Star-Inc-L0000391998 Saxony-Ii-Barber-Shop-L0000392491 Test-L0000392334 我想做的是把范围缩小到以下几点: New-England-Center-For-Children Southboro-Housing
New-England-Center-For-Children-L0000392290
Southboro-Housing-Authority-L0000392464
Crew-Star-Inc-L0000391998
Saxony-Ii-Barber-Shop-L0000392491
Test-L0000392334
我想做的是把范围缩小到以下几点:
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Test
有人能帮忙吗?
awk
喜欢这些东西:
$ awk -F[/-] -v OFS="-" '{print $(NF-3), $(NF-2)}' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
这将/
和-
设置为可能的字段分隔符。基于它们,它打印最后一个字段-3和最后一个字段-2,由分隔符-
分隔。请注意,$NF
代表最后一个参数,因此$(NF-1)
是倒数第二个参数,以此类推
此
sed
也很有帮助:
$ sed -r 's#.*/(\w*-\w*)-\w*\.\w*</loc>$#\1#' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
它选择块-L
+某物+行尾的所有内容,并将其打印回来
您还可以使用另一个技巧:
rev file | cut -d- -f2- | rev
因为您需要的是
-
分隔字段的每个片段,所以让我们获取除最后一个字段之外的所有字段。怎样通过倒转线路,从第二条线路上取下所有线路,然后倒转回来。awk
喜欢这些东西:
$ awk -F[/-] -v OFS="-" '{print $(NF-3), $(NF-2)}' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
这将/
和-
设置为可能的字段分隔符。基于它们,它打印最后一个字段-3和最后一个字段-2,由分隔符-
分隔。请注意,$NF
代表最后一个参数,因此$(NF-1)
是倒数第二个参数,以此类推
此
sed
也很有帮助:
$ sed -r 's#.*/(\w*-\w*)-\w*\.\w*</loc>$#\1#' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
它选择块-L
+某物+行尾的所有内容,并将其打印回来
您还可以使用另一个技巧:
rev file | cut -d- -f2- | rev
因为您需要的是-
分隔字段的每个片段,所以让我们获取除最后一个字段之外的所有字段。怎样将第二行中的所有内容倒过来,然后倒回去。问题的第1版
输入的第一个版本是HTML格式,必须在所需文本之前和之后删除部分:
$ sed -r 's|.*[A-Z]/([a-zA-Z-]+)-L0.*|\1|' input
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
问题的第二版
在修订后的问题中,只需删除以-L00
开头的文本:
$ sed 's|-L00.*||' input2
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
这两个命令都使用一个“替换”命令。该命令的形式为s | old | new |
问题的第1版
输入的第一个版本是HTML格式,必须在所需文本之前和之后删除部分:
$ sed -r 's|.*[A-Z]/([a-zA-Z-]+)-L0.*|\1|' input
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
问题的第二版
在修订后的问题中,只需删除以-L00
开头的文本:
$ sed 's|-L00.*||' input2
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
这两个命令都使用一个“替换”命令。该命令的形式为
s | old | new |
下面是我使用Perl的方法:
perl -nle 'm{example[.]com/bp/(.*?)/(.*?)-L\d+[.]htm} && print $2' filename
注意:原始问题与输入行匹配,如下所示:
<loc>http://www.example.com/bp/Lowell-MA/Special-Restaurant-L0000423916.htm</loc>
<loc>http://www.example.com/bp/Houston-TX/Eliot-Cleaning-L0000422797.htm</loc>
<loc>http://www.example.com/bp/New-Orleans-LA/Kennedy-Plumbing-L0000423121.htm</loc>
将仅在正则表达式匹配时打印。如果正则表达式包含捕获括号,您可以将第一个捕获的部分称为$1,第二个部分称为$2,以此类推
如果您的正则表达式包含斜杠,使用不同的正则表达式分隔符('m'代表'match')可能会更简洁:
如果您有现代Perl,可以使用-E启用现代功能,并使用say
而不是print
以添加换行符进行打印:
perl -nE 'm{example[.]com/bp/(.*?)/(.*?)-L\d+[.]htm} && say $2' filename
下面是我如何使用Perl实现的:
perl -nle 'm{example[.]com/bp/(.*?)/(.*?)-L\d+[.]htm} && print $2' filename
注意:原始问题与输入行匹配,如下所示:
<loc>http://www.example.com/bp/Lowell-MA/Special-Restaurant-L0000423916.htm</loc>
<loc>http://www.example.com/bp/Houston-TX/Eliot-Cleaning-L0000422797.htm</loc>
<loc>http://www.example.com/bp/New-Orleans-LA/Kennedy-Plumbing-L0000423121.htm</loc>
将仅在正则表达式匹配时打印。如果正则表达式包含捕获括号,您可以将第一个捕获的部分称为$1,第二个部分称为$2,以此类推
如果您的正则表达式包含斜杠,使用不同的正则表达式分隔符('m'代表'match')可能会更简洁:
如果您有现代Perl,可以使用-E启用现代功能,并使用say
而不是print
以添加换行符进行打印:
perl -nE 'm{example[.]com/bp/(.*?)/(.*?)-L\d+[.]htm} && say $2' filename
这方面的perl代码是:
perl-nle'print$1 if(m{-.*?/(.*?-.*?)
我们可以将正则表达式分解为以下匹配项:
因为这是城市和州之间的事-
匹配使正则表达式工作的最小字符集,即状态*?
匹配状态和所需数据之间的斜杠/
开始捕获您感兴趣的数据(
将匹配您关心的数据*?-*?
将结束捕获)
将匹配L########前的破折号,以便在数据之后为正则表达式提供一些匹配的内容。这将阻止最小正则表达式匹配0个字符-
然后print语句将打印出捕获的内容(您的数据)。这方面的perl代码将是:
perl-nle'print$1 if(m{-.*?/(.-.*?)
我们可以将正则表达式分解为以下匹配项:
因为这是城市和州之间的事-
匹配使正则表达式工作的最小字符集,即状态*?
匹配状态和所需数据之间的斜杠/
开始捕获您感兴趣的数据(
将匹配您关心的数据*?-*?
将结束捕获)
将匹配L########前的破折号,以便在数据之后为正则表达式提供一些匹配的内容。这将阻止最小正则表达式匹配0个字符-
然后,print语句将打印出捕获的内容(您的数据)。使用GNU
awk
:
awk -F\- 'NF--' OFS=\- file
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
- 将输入和输出字段分隔符设置为
李>-
包含多个字段。将其减少1以删除最后一个字段李>NF
sed
:
sed 's/\(.*\)-.*/\1/' file
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
- 简单贪婪的正则表达式匹配到最后一个连字符李>
- 替换时,使用捕获的组并丢弃其余组
- 使用GNU
awk
:
awk -F\- 'NF--' OFS=\- file
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
- 将输入和输出字段分隔符设置为
李>-
包含多个字段。将其减少1以删除最后一个字段李>NF
sed
:
sed 's/\(.*\)-.*/\1/' file
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
- 与l匹配的简单贪婪正则表达式