Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 使用命令行删除文本?_Perl_Shell_Text_Command Line - Fatal编程技术网

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
  • 将输入和输出字段分隔符设置为
    -
  • NF
    包含多个字段。将其减少1以删除最后一个字段
使用
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
      
      • 将输入和输出字段分隔符设置为
        -
      • NF
        包含多个字段。将其减少1以删除最后一个字段
      使用
      sed

      sed 's/\(.*\)-.*/\1/' file
      New-England-Center-For-Children
      Southboro-Housing-Authority
      Crew-Star-Inc
      Saxony-Ii-Barber-Shop
      Test
      
      • 与l匹配的简单贪婪正则表达式