【问题标题】:How to GREP words, not lines, that contain specific characters, and print entire word如何 GREP 包含特定字符的单词,而不是行,并打印整个单词
【发布时间】:2016-04-07 16:07:56
【问题描述】:

我有一个包含大量行和单词的文件,例如这个例子:

C742 C743 C744 C745 C835 C836 C837 C838 C839 C840 C841 C842 C843 C844 C845 C935 C936 C937 C938 C939 C940 C941 C942 C943 C944 C945 C1035 C1036 C1037 C1038 C1039 C1040 C1041 C1042 C1043 C1044 C1045 D135 D136 D137 D138 D139 D140 D141 D142 D143 D144 D145 D235 D236 D237 D238 D239 D240 D241 D242 D243 D244 D245 D335 D336 D337 D338 D339 D340 D341 D342 D343 D344 D345 D435 D436 D437 D438 D439 D440 D441 D442 D443 D444

我想要做的是只列出包含特定数字的单词(假设每个 4 个字符包是一个单词),例如35

在这个例子中,我希望打印的结果是:

C835
C935
C1035
D135
D235
D335
D435

我尝试了几种不同的方法,例如使用 grep 仅查找包含 35 的整行被打印,或者 grep -o 35 仅打印 35 并且我不知道前缀是什么那个数字是。

【问题讨论】:

  • 我尝试过使用 Grep 和一些选项,但没有别的。我是 bash 脚本的初学者,所以我知道必须快速解决这个问题,但我无法想出它。下面的几个人能够向我展示几行来完成工作,谢谢!
  • 你想使用 Python 还是 bash?
  • @KevinGuan 他可能不在乎哪种语言,而是如果它能解决他的问题。

标签: python regex linux bash ubuntu


【解决方案1】:

试试下面的 bash 脚本:

cat words.txt | tr " " "\n" | grep 35

说明:

cat 读取 words.txt 并将它们吐出到 STDOUT,然后通过管道传输到 tr,这意味着“翻译”:在这种情况下,从空格(“”)到换行符(“\n”),然后, grep 只是执行其默认的逐行行为并搜索包含 35 的任何内容。

【讨论】:

  • 哇,这太棒了!我是 bash 脚本的初学者,但我正在努力理解这个脚本。您介意解释一下这是如何工作的吗?
  • @EricAngel Cat 读取 words.txt 并将其吐出 STDOUT,然后通过管道传输到 tr 中,意思是“翻译”:在这种情况下,从空格(“”)到换行符(“\n”),然后,grep 只是执行默认的逐行行为并搜索包含 35 的任何内容。
  • 非常有道理,感谢您的帮助 Pato-Sáinz
  • 您可以避免使用tr " " "\n" < words.txt | grep 35 调用cat
【解决方案2】:

试试这个

for word in `cat filename`; do
    echo $word | grep 35
done

【讨论】:

  • @EricAngel:如果答案是正确的,记得接受它。
【解决方案3】:

Python:

import re
s = "C742 C743 C744 C745 C835 C836 C837 C838 C839 C840 C841 C842 C843 C844 C845 C935 C936 C937 C938 C939 C940 C941 C942 C943 C944 C945 C1035 C1036 C1037 C1038 C1039 C1040 C1041 C1042 C1043 C1044 C1045 D135 D136 D137 D138 D139 D140 D141 D142 D143 D144 D145 D235 D236 D237 D238 D239 D240 D241 D242 D243 D244 D245 D335 D336 D337 D338 D339 D340 D341 D342 D343 D344 D345 D435 D436 D437 D438 D439    D440 D441 D442 D443 D444"
print(re.findall(r'[A-Z0-9]*35[0-9]*',s)) # assuming '35' can appear anywhere in the number.

输出:

['C835', 'C935', 'C1035', 'D135', 'D235', 'D335', 'D435']

您可以使用以下命令读取整个文件:

with open('words.txt') as f:
    s = f.read()

【讨论】:

    【解决方案4】:

    如果你也想用 Python 来做:

    >>> with open('file') as f:
    ...     print('\n'.join(i for i in f.read().split() if '35' in i))
    ...     
    ... 
    C835
    C935
    C1035
    D135
    D235
    D335
    D435
    

    这里,f.read() 获取文件的内容并将内容作为字符串对象返回。 str.split() 用空格分割字符串并返回一个列表。

    但是,(i for i in f.read().split() if '35' in i) 是 Python 中的生成器理解,它返回一个生成器,并且元素中只有 '35'。所以我们可以使用它来获得期望的输出(在这种情况下不需要正则表达式)。

    最后,使用'\n'.join() 将它们打印出来。您也可以改用for 循环:

    >>> with open('file') as f:
    ...     for i in (i for i in f.read().split() if '35' in i):
    ...         print(i)
    ...         
    ...     
    ... 
    C835
    C935
    C1035
    D135
    D235
    D335
    D435
    

    【讨论】:

      【解决方案5】:

      你可以扩展你的正则表达式来匹配所有的组,但是有点乱:

      grep -o "[^ ]*35[^ ]*" words.txt
      

      上面的[^ ]* 部分将匹配任何非空格字符。

      【讨论】:

        【解决方案6】:

        有一个标准的 grep 解决方案(\S 表示非空白字符)

        $ grep -o '\S*35\S*' words.txt
        C835                                                                                                                  
        C935                                                                                                                  
        C1035                                                                                                                 
        D135                                                                                                                  
        D235                                                                                                                  
        D335                                                                                                                  
        D435  
        

        【讨论】:

        • 嗨。感谢您的解决方案!有什么方法可以解释这个“非空白字符”是如何工作的?我认为星号正在调用以匹配任何字符,并且 -o 匹配确切的单词,但我无法弄清楚其余的。 grep 的手册页没有显示任何 /S 或 /s 参数。谢谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-06
        • 2015-07-30
        • 2015-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多