如何删除某个模式或文件中的字符串之后的每一行的其余部分?


21

假设我在文本文件中有一个URL列表:

google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

我想删除“ .com”之后的所有内容。

预期成绩:

google.com
unix.stackexchange.com
isuckatunix.com

我试过了

sed 's/.com*//' file.txt 

但它也删除.com了。


您是否有特定原因只想搜索.com而不是删除第一个/字符之后(包括第一个字符)的所有内容?如果您en.wikipedia.org/wiki/Ubuntu的列表中有类似URL的网址怎么办?
字节指挥官

Answers:


17

要显式删除“ .com”之后的所有内容,只需调整现有的sed解决方案即可将“ .com(anything)”替换为“ .com”:

sed 's/\.com.*/.com/' file.txt

我对您的正则表达式进行了调整,以避开第一期;否则,它将与“ thisiscommon.com/something”之类的内容匹配。

请注意,您可能希望使用尾随的正斜杠进一步锚定“ .com”模式,以免意外裁剪“ sub.com.domain.com/foo”之类的内容:

sed 's/\.com\/.*/.com/' file.txt

9

您可以通过以下方式使用awk的字段分隔符(-F):

$ cat file
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

$ cat file | awk -F '\\.com' '{print $1".com"}'
google.com
unix.stackexchange.com
isuckatunix.com

说明:

NAME
       awk - pattern scanning and processing language

-F fs
       --field-separator fs
              Use fs for the input field separator (the value of the FS predefined variable).

当您要删除之后的所有内容时.com,请-F '.com'与分隔行.comprint $1仅输出之前的部分.com。因此,$1".com"添加.com并为您提供预期的输出。




1
@Pandya:这会失败,例如acomercial.com/asdsad
cuonglm '16

@cuonglm感谢您指出。改进的答案
潘迪

4

用于非交互式就地文件编辑的最佳工具是ex

ex -sc '%s/\(\.com\).*/\1/ | x' file.txt

如果您曾经使用过vi并且曾经键入过以冒号开头的命令,:那么您将使用ex命令。当然,您可以通过这种方式执行的许多更高级或“特别”的命令都是Vim扩展(例如:bufdo),并且未在POSIX规范中ex定义,但是这些规范在非可视化中提供了真正惊人的功能和灵活性。文本编辑(交互式或自动)。

上面的命令包含几个部分。

-s启用静音模式以准备ex批量使用。(禁止输出消息等。)

-c指定一旦file.txt在缓冲区中打开文件(在本例中为)后执行的命令。

%是一个等效于地址的地址说明符1,$—表示将以下命令应用于缓冲区的所有行。

s是您可能已经熟悉的替代命令。尽管某些高级正则表达式功能可能因实现方式而有所不同,但它通常用于命令中vi并具有与s命令sed基本相同的功能。在这种情况下,从“ .com”到行尾的内容将仅替换为“ .com”。

竖线分隔要执行的顺序命令。在许多(大多数)ex实现中,您还可以使用其他-c选项,例如:

ex -sc '%s/\(\.com\).*/\1/' -c x file.txt

但是,POSIX不需要这样做。

x任何更改写入文件后,该命令将退出。与wq表示“写入并退出”的含义不同,x仅当缓冲区已被编辑时才写入文件。因此,如果您的文件未更改,则将保留时间戳。


1
+1使用
杰夫·夏勒

1
它不会就地编辑。至少,它没有比Gnu sed的伪造-i多。它读取/写入磁盘缓冲区。亲自查看w / ex -rpreserve命令。
mikeserv '16

@mikeserv preserve命令是什么?
Mateen Ulhaq

2

非常快速,简单且肮脏的python方式:

#!/usr/bin/env python
import sys
with open( sys.argv[1]  ) as file:
    for line in file:
        print line.split("/")[0]

样品运行

skolodya@ubuntu:$ chmod +x removeStrings.py                                   

skolodya@ubuntu:$ ./removeStrings.py strings.txt                              
google.com
unix.stackexchange.com
isuckatunix.com


skolodya@ubuntu:$ cat strings.txt                                             
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

2
我能知道不赞成投票的理由吗?
Sergiy Kolodyazhnyy,2016年

3
它可以工作,但并不在乎.com,它只是删除从/该行的第一个开始的所有内容。(在我看来,这是更好的方法!)
Byte Commander

1
@ByteCommander完全正确!如果域名是.net,则在其他方法中,域名和扩展名后的部分不会被删除,因此/用作分隔符会更安全。
Sergiy Kolodyazhnyy

+1的答案和评论使我感到自己在AskUbuntu.com:D
WinEunuuchs2Unix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.