我有一个巨大的文件,其中包含遵循以下格式的行:
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
任何人都可以帮忙吗?
答案 0 :(得分:2)
使用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
答案 1 :(得分: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|
。
答案 2 :(得分:1)
这个perl代码是:perl -nle'print $1 if(m{-.*?/(.*?-.*?)-})
我们可以将正则表达式分解为匹配以下内容:
-
表示城市和州之间的情况.*?
匹配使正则表达式工作的最小字符集,即状态/
匹配State和您想要的数据之间的斜杠(
开始捕获您感兴趣的数据.*?-.*?
将与您关注的数据相匹配)
将关闭捕获-
将匹配L #######之前的破折号,以便在数据之后为正则表达式提供匹配的内容。这将阻止最小的正则表达式匹配0个字符。然后print语句将打印出捕获的内容(您的数据)。
答案 3 :(得分:0)
awk
喜欢这些东西:
$ awk -F[/-] -v OFS="-" '{print $(NF-3), $(NF-2)}' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
这会将/
和-
设置为可能的字段分隔符。基于它们,它打印由分隔符-
分隔的last_field-3和last_field-2。请注意,$NF
代表最后一个参数,因此$(NF-1)
是倒数第二个,等等。
此sed
也很有用:
$ sed -r 's#.*/(\w*-\w*)-\w*\.\w*</loc>$#\1#' file
Special-Restaurant
Eliot-Cleaning
Kennedy-Plumbing
在斜杠word-word
之后选择块/
,然后跟word.word</loc>
+ end_of_line。然后,它打印回这个块。
根据您的新输入,可以实现:
$ sed -r 's/(.*)-L\w*$/\1/' file
New-England-Center-For-Children
Southboro-Housing-Authority
Crew-Star-Inc
Saxony-Ii-Barber-Shop
Test
选择块-L
+某物+行尾的所有内容,并将其打印回来。
您还可以使用另一种技巧:
rev file | cut -d- -f2- | rev
正如你想要的那样,每一片-
个分隔的字段,让我们得到所有这些,但最后一个。怎么样?通过反转线,将所有线从第二个线上移开然后反转。
答案 4 :(得分:0)
以下是我用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>
-n选项告诉Perl循环遍历文件的每一行(但不打印出来)。
-l选项在每个打印的末尾添加换行符
-e&#39; perl-code&#39;选项为每行输入执行perl-code
模式:
/regex/ && print
仅在正则表达式匹配时才会打印。如果正则表达式包含捕获括号,您可以将第一个捕获的部分称为$ 1,第二个作为$ 2等。
如果你的正则表达式包含斜杠,使用不同的正则表达式分隔符可能更清晰(&#39; m&#39;代表&#39;匹配&#39;):
m{regex} && print
如果你有一个现代的Perl,你可以使用-E来启用现代功能,并使用say
而不是print
来打印附加的换行符:
perl -nE 'm{example[.]com/bp/(.*?)/(.*?)-L\d+[.]htm} && say $2' filename
答案 5 :(得分:0)
这在Perl中非常简洁
perl -i.bak -lpe's/-[^-]+$//' myfile
请注意,这会修改输入文件就地,但会保留原始数据的备份,并调用myfile.bak