Bash 使用grep提取单个单词

Bash 使用grep提取单个单词,bash,shell,Bash,Shell,我有以下类型的条纹。它们都是一根大绳子的一部分 。。。。。。UUID:a062832a;UID:Z6IxbK9;UUID:null 。。。。。。UUID:a062832a;UID:Z6IxbK9 。。。。。。UID:Z6IxbK9;UUID:null 我想提取与UID关联的值,即Z6IxbK9。现在我使用下面的表达式来提取它 value=`echo $line | grep -o '\<UID.*\>' | awk -F\; '{ print $1 }' | cut -d: -f2

我有以下类型的条纹。它们都是一根大绳子的一部分

  • 。。。。。。UUID:a062832a;UID:Z6IxbK9;UUID:null
  • 。。。。。。UUID:a062832a;UID:Z6IxbK9
  • 。。。。。。UID:Z6IxbK9;UUID:null
  • 我想提取与UID关联的值,即
    Z6IxbK9
    。现在我使用下面的表达式来提取它

    value=`echo $line | grep -o '\<UID.*\>' | awk -F\; '{ print $1 }' | cut -d: -f2 | tr -d ' '`
    
    value='echo$line | grep-o'\'| awk-F\'{print$1}'| cut-d:-f2 | tr-d''`
    
    我觉得这不是一个有效的方法。我使用了四个不同的命令,这会减慢大文件的处理速度


    有人能提出更好的解决方案吗

    与非贪婪匹配
    *?
    一起玩
    -p
    (perl regexp),例如,尝试以下方法:

     grep -P -o ' UID:.*?;' file | sed 's/ UID: //;s/;//'
    
    结果:

    $ echo '...stuff stuff... UUID: a062832a; UID: ABCZ6IxbK9; UUID: null; ......
        ..foo bar.... UUID: a062832a; UID: DEFZ6IxbK9; ......
        .. hello.... UID: ghiZ6IxbK9; UUID: null; ......
    ' | grep -P -o ' UID:.*?;' | sed 's/ UID: //;s/;//'
    
    ABCZ6IxbK9
    DEFZ6IxbK9
    ghiZ6IxbK9
    

    您可以使用
    awk

    string="...... UUID: a062832a; UID: Z6IxbK9; UUID: null; ......
    ...... UUID: a062832a; UID: Z6IxbK9; ......
    ...... UID: Z6IxbK9; UUID: null; ......"
    
    awk '
    {
        for(i=1;i<=NF;i++) 
            if($i == "UID:") { 
                s=$(i+1)
                sub(";","",s)
                print s
            }
    }' <<<"$string"
    
    此“
    awk
    -
    sed
    ”组合:

    awk-F'UID:“{print$2}”文件| sed's/;.*/'

    给出:

     Z6IxbK9
     Z6IxbK9
     Z6IxbK9
    

    您可以通过使用
    -p
    (Perl regex)参数的单个grep命令简单地实现这一点

    $ grep -oP '\bUID:\s*\K[^;]*' file
    Z6IxbK9
    Z6IxbK9
    Z6IxbK9
    
    说明:

    • \b
      匹配单词字符和非单词字符的单词边界
    • UID:\s*
      匹配字符串
      UID:
      以及以下空格
    • \K
      这将丢弃先前匹配的字符,在本例中,它是
      UID:
    • [^;]*
      现在它匹配任何不属于
      的字符零次或多次
      
        为什么不干脆
        sed-n$'s/^.[^U]UID:[\040\t]*\\([^;]*\\).$/\\1/p'

        grep
        后面看:

        $ cat file
        ...... UUID: a062832a; UID: Z6IxbK9; UUID: null; ......
        ...... UUID: a062832a; UID: Z6IxbK9; ......
        ...... UID: Z6IxbK9; UUID: null; ......
        
        $ grep -oP '(?<=\bUID: )[^;]*' file
        Z6IxbK9
        Z6IxbK9
        Z6IxbK9
        
        $cat文件
        ...... UUID:a062832a;UID:Z6IxbK9;UUID:null。。。。。。
        ...... UUID:a062832a;UID:Z6IxbK9。。。。。。
        ...... UID:Z6IxbK9;UUID:null。。。。。。
        
        $grep-oP'(?您应该能够在
        awk
        中完成这一切。它可以使用
        sub()
        处理正则表达式,并且可以使用
        split()
        拆分字符串。谢谢Barmar。您有什么建议,我可以在这里查看有关sub和split()的更多信息吗?)。它们在
        awk
        手册页中有描述。谢谢jimmij,您的解决方案至少给了我UID:xxxx。现在我可以删除awk。您是否有任何文档或链接解释?的用法grep@Abhijeet通常GNU grep不允许非贪婪匹配,因此
        -P
        选项告诉您如何使用perl regexp顺便说一句,我在我的答案中添加了sed-in-pipe,以便只匹配UID后面的字符串。注意:从逻辑上讲,这与@AvinashRaj的答案类似,但语法不同。
        $ cat file
        ...... UUID: a062832a; UID: Z6IxbK9; UUID: null; ......
        ...... UUID: a062832a; UID: Z6IxbK9; ......
        ...... UID: Z6IxbK9; UUID: null; ......
        
        $ grep -oP '(?<=\bUID: )[^;]*' file
        Z6IxbK9
        Z6IxbK9
        Z6IxbK9
        
        \bUID - UID, preceded by white-space.
        (?<=\bUID) - Any text preceded by \bUID
        [^;]* - anything till (& not including) a ';'