【问题标题】:Extract substring after a character提取字符后的子字符串
【发布时间】:2016-04-04 22:48:45
【问题描述】:

我正在尝试在最后一个句点(点)之后提取子字符串。 下面的例子。

  • echo "filename..txt" 应该返回“txt”
  • echo "filename.txt." 应该返回 ""
  • echo "filename" 应该返回 ""
  • echo "filename.xml" 应该返回“xml”

我在下面尝试过。但仅当字符(点)存在一次时才有效。但我的文件名可能有(点)0 次或更多次。

echo "filename.txt" | cut -d "." -f2

【问题讨论】:

标签: linux unix sed substring cut


【解决方案1】:

可以通过以下方式使这个可移植(因此它不是仅限 Linux),避免 ERE 依赖:

$ sed -ne 's/.*\.//p' <<< "file..txt"
txt
$ sed -ne 's/.*\.//p' <<< "file.txt."

$ sed -ne 's/.*\.//p' <<< "file"
$ sed -ne 's/.*\.//p' <<< "file.xml"
xml

请注意,出于测试目的,我在 bash 中使用了“here-string”。如果您的 shell 不是 bash,请使用您的 shell 用于向 sed 提供数据的任何内容。

这里的重要一点是使用 sed 的 -n 选项,它告诉它默认不打印任何东西,结合 substitute 命令的显式 p 标志,它告诉 sed only 在成功替换时打印,这显然需要在模式中包含一个点。

使用此解决方案,"file.txt.""file" 之间的区别在于前者返回的输入行替换为 null(因此您可能仍会根据您的使用情况得到换行符),而后者则不返回任何内容,如 @没有指示 987654326@ 打印,因为输入中不包含 .。当然,最终结果很可能是相同的:

$ printf "#%s#\n" $(sed -ne 's/.*\.//p' <<< "file.txt.")
##
$ printf "#%s#\n" $(sed -ne 's/.*\.//p' <<< "file")
##

【讨论】:

    【解决方案2】:

    让我们使用awk

    awk -F"." '{print (NF>1)? $NF : ""}' file
    

    这会将字段分隔符设置为. 并打印最后一个。但如果没有,它会打印一个空字符串。

    测试

    $ cat file
    filename..txt
    filename.txt.
    filename
    filename.xml
    $ awk -F"." '{print (NF>1)? $NF : ""}' file
    txt
    
    
    xml
    

    【讨论】:

      【解决方案3】:

      使用 sed 分两步:首先删除不带点的字符串,然后删除直到最后一个点:

      sed -e 's/^[^.]*$//' -e 's/.*\.//'
      

      测试:

      for s in file.txt.. file.txt. file.txt filename file.xml; do
         echo "$s -> $(echo "$s" | sed -e 's/^[^.]*$//' -e 's/.*\.//')"
      done
      

      测试结果:

      file.txt.. ->
      file.txt. ->
      file.txt -> txt
      filename ->
      file.xml -> xml
      

      其实@ghoti 的答案大致相同,只是短了一点(更好)。 其他想要用另一种语言做类似事情的读者可以使用此解决方案。

      【讨论】:

        【解决方案4】:

        用 awk 做起来很简单:

        awk -F"." '{ print $NF }'
        

        这是做什么的:使用点作为分隔符,从输入中提取最后一个字段。

        【讨论】:

        • 无扩展案例失败。但这很容易通过添加/\./ 来解决(如果空输出,没有空行,可以接受,否则使用/\./{print $NF;next} {print ""})。
        猜你喜欢
        • 2019-11-19
        • 1970-01-01
        • 2015-06-06
        • 1970-01-01
        • 2014-02-13
        • 2021-09-08
        • 2011-07-21
        • 1970-01-01
        相关资源
        最近更新 更多