【问题标题】:Linux shell extracting substring between matching patternsLinux shell在匹配模式之间提取子字符串
【发布时间】:2019-02-05 22:22:21
【问题描述】:

假设我有一个字符串poskek|gfgfd|XLSE|a1768|d234|uijjk,我只想提取LSE 部分。

我只知道在LSE前面会有|X,在我感兴趣的部分后面直接有|LSE

【问题讨论】:

  • 这是我正在尝试的代码:echo 'poskek|gfgfd|XLSE|a1768|d234|uijjk' | sed 's/.*|X([^|]\+).*/\1/'

标签: regex linux bash


【解决方案1】:

使用sed 的另一个答案应该可以,但我总是发现sed 对于正则表达式的选择有点尴尬,因为它实际上是为了替换(因此为什么模式的任何一侧都需要与@987654323 @ 和你真正想要的部分需要放在括号中)。这是使用grep的解决方案:

grep -Po '\|X\K[^|]+'

-Pgrep 发出信号以使用更高级的 Perl 正则表达式引擎

-o 只打印该行的匹配部分

\|X 匹配文字竖线和大写 X

\K忘记当前匹配的内容(不要包含在最终输出中)

[^|]+除竖线以外的一个或多个字符

【讨论】:

  • 我试过你的解决方案,它不起作用。我尝试的代码如下:echo 'poskek|gfgfd|XLSE|a1768|d234|uijjk' | grep -Po '\|X\K[^|]+',我收到以下错误消息:usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...] –
  • @JunsuiBantsu 看起来您的 grep 缺少 -P 选项。输入grep --version 会得到什么?
  • 我明白了:grep (BSD grep) 2.5.1-FreeBSD
  • 您使用的是 FreeBSD/OSX?这解释了你一直遇到的问题。为什么你的问题的标题是 Linux?
  • 我是一个新手我不知道区别我认为所有非 Windows Shell 本质上都是 Linux /Unix。那么如何解决我在 OSX 上的问题呢?
【解决方案2】:

作为纯 bash 解决方案,请尝试:

str='poskek|gfgfd|XLSE|a1768|d234|uijjk'
ext=${str#*|X}
ext=${ext%%|*}
echo "$ext"

如果正则表达式可用,以下也可以:

if [[ $str =~ .*\|X([^|]+) ]]; then
    echo "${BASH_REMATCH[1]}"
fi

【讨论】:

  • if [[ $str =~ \|X([^|]+) ]];
【解决方案3】:
echo 'poskek|gfgfd|XLSE|a1768|d234|uijjk' | sed -n 's/.*|X\([^|]\+\).*/\1/p'

这应该可以解决问题。

解释:

sed -n 除非指定,否则不会打印任何内容

s/ - 搜索和替换
.*|X - 匹配直到并包括|X的所有内容
\([^|]\+\) - 捕获多个(至少一个)不是|的字符.* - 匹配其余文本(只是为了“吃掉它”)
/\1/p - 用第一个捕获替换所有匹配的文本,然后打印

【讨论】:

  • 我用以下代码尝试了你的答案,但它不起作用。我把整个字符串都拿回来了。 echo 'poskek|gfgfd|XLSE|a1768|d234|uijjk' | sed 's/.*|X([^|]\+).*/\1/'
  • 您输入的内容不是我写的逐字记录...我将更新我的答案,不为不匹配的行打印任何内容,并且您必须在您的粘贴 =)
【解决方案4】:

对于这种特殊情况,您可以做一些非常规的做法:

awk '$1=="X"{$1="";print}' FS= OFS= RS=\|

【讨论】:

    【解决方案5】:

    试试这个

     echo 'poskek|gfgfd|XLSE|a1768|d234|uijjk' | 
       awk -F "|" '{for(i=1;i<=NF;++i) printf "%s", (substr($i,1,1)=="X"?substr($i,2):"")}'
    

    在哪里

    -F 是字段分隔符 => '|' NF 是字段数

    【讨论】:

    • OP 不要求第三组;他们要求以X 开头的组
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 2010-10-27
    • 2019-02-25
    相关资源
    最近更新 更多