【问题标题】:grep only one occurrencegrep 只出现一次
【发布时间】:2016-03-15 20:17:45
【问题描述】:

我正在尝试抓取一些内容,但在同一行中有多个实例。我正在使用这个命令。

grep -o -m 1 -P '(?<=sk).*(?=fa)' test.txt | head -1

但是,搜索在第二个/最后一个匹配之后结束。在 Ubuntu 14.04.2 上运行它

test.txt: skjahfasdkl aklsdj laks skjahfasdkl aklsdj laks
Current Output: jahfasdkl aklsdj laks skjah
Desired output: jah

【问题讨论】:

  • 刚刚粘贴了样本数据和当前输出。
  • 贪婪地寻找从第一个“sk”到最后一个“fa”的最长匹配项
  • 所以你的输入文件只有一行?

标签: linux shell unix grep


【解决方案1】:

你只需要不贪心:

grep -m1 -oP '(?<=sk).*?(?=fa)' file | head -1
# ...................^^^

-m1 将在第一行 之后停止,但您仍然需要 head 来限制到第一行 匹配

【讨论】:

  • 完美无缺。 :)
【解决方案2】:

这是贪婪匹配,您想将空格视为分隔符,因此指定匹配非空格字符,即

    ... '(?<=sk)[^ ]*(?=fa)'

【讨论】:

    【解决方案3】:

    如果条件是 sk 和 fa 之间非空格(单词匹配),可以使用 can use [^ ]* 代替 .*,如下:

    grep -o -m 1 -P '(?<=sk)[^ ]*(?=fa)' test.txt | head -1
    

    否则你可以使用这个:

    sed -e "s/sk\(.*\)fa.*$/\1/g" test.txt | sed -e "s/fa.*$//g"
    

    测试:

    echo "skjahz z zfasdkl aklsdj laks skjahppppfasdkl aklsdj laks" | sed -e "s/sk\(.*\)fa.*$/\1/g" | sed -e "s/fa.*$//g"
    
    #jahz z z
    

    【讨论】:

      【解决方案4】:

      如果您考虑非 grep 答案,那么这个 gnu-awk 可以完成这项工作:

      awk -v FPAT='sk[^[:blank:]]*fa' '{gsub(/^sk|fa$/, "", $1); print $1; exit}' file
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-10
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 2015-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多