【问题标题】:How to get the release value?如何获取发布值?
【发布时间】:2021-12-12 00:19:19
【问题描述】:

我有一个具有以下名称格式的文件:

rzp-QAQ_SA2-5.12.0.38-quality.zip
rzp-TEST-5.12.0.38-quality.zip
rzp-ASQ_TFC-5.12.0.38-quality.zip

我希望上述文件名中的值为:5.12.0.38-quality.zip

我正在尝试如下,但没有得到正确的值:

echo "$fl_name" | sed 's#^[-[:alpha:]_[:digit:]]*##'

fl_name 是包含文件名的变量。

提前非常感谢!

【问题讨论】:

  • 这个问题有 grep、cut 和 bash 的答案,所以恕我直言,如果我们保留这些标签,这可能对未来的访问者有用,以获得各种答案/解决方案。所以在这里添加回标签。

标签: regex sed grep cut


【解决方案1】:

在这里使用cut 更容易:

cut -d- -f3- file

5.12.0.38-quality.zip
5.12.0.38-quality.zip
5.12.0.38-quality.zip

如果您想要sed,请使用:

sed -E 's/^([^-]*-){2}//' file

5.12.0.38-quality.zip
5.12.0.38-quality.zip
5.12.0.38-quality.zip

【讨论】:

    【解决方案2】:

    您与同一字符类中的所有 alpha、数字 -_ 匹配太多。

    您可以匹配 alpha 和 - 以及可选的 _ 和字母数字

    sed -E 's#^[-[:alpha:]]+(_[[:alnum:]]*-)?##' file
    

    或者你可以缩短第一个字符类,并在末尾匹配一个-

    sed -E 's#^[-[:alnum:]_]*-##' file
    

    两个例子的输出

    5.12.0.38-quality.zip
    5.12.0.38-quality.zip
    5.12.0.38-quality.zip
    

    【讨论】:

      【解决方案3】:

      使用 GNU grep,您可以尝试以下代码。使用所示示例编写和测试。

      grep -oP '(.*?-){2}\K.*'  Input_file
      

      作为替代用途(使用非捕获组解决方案,根据第四只鸟的好建议):

      grep -oP '(?:[^-]*-){2}\K.*' Input_file
      

      解释:在这里使用 GNU grep。在grep 程序中使用-oP 选项,该选项用于匹配精确匹配的值并在程序中分别启用PCRE 风格。然后在主程序中,使用正则表达式(.*?-){2} 意味着,在这里使用惰性匹配直到- 2 次(在这里获得- 的前2 个匹配项)然后使用\K 选项,以确保直到现在匹配值被遗忘,只会打印下一个提到的正则表达式匹配值,这将在此处打印其余值。

      【讨论】:

        【解决方案4】:

        假设:

        • 所有文件名都包含 3 个连字符 (-)
        • 所需的结果始终包括剥离前两个连字符分隔的字符串
        • OP 希望对变量执行此操作

        我们可以通过使用参数替换来消除子进程调用的开销(例如,grepcutsed):

        $ f1_name='rzp-ASQ_TFC-5.12.0.38-quality.zip'
        
        $ new_f1_name="${f1_name#*-}"                     # strip off first hyphen-delimited string
        $ echo "${new_f1_name}"
        ASQ_TFC-5.12.0.38-quality.zip
        
        $ new_f1_name="${new_f1_name#*-}"                 # strip off next hyphen-delimited string
        $ echo "${new_f1_name}"
        5.12.0.38-quality.zip
        

        另一方面,如果 OP 将文件名列表提供给循环构造,并且不需要原始文件名,则在循环处理之前对文件名列表执行批量操作可能会更容易,例如:

        while read -r new_f1_name
        do
            ... process "${new_f1_name)"
        
        done < <( command-that-generates-list-of-file-names | cut -d- -f3-)
        

        【讨论】:

          【解决方案5】:

          在普通的 bash 中:

          echo "${fl_name#*-*-}"
          

          【讨论】:

            【解决方案6】:

            Perl 解决方案捕获 '-' 结尾的数字和字符

            cat f_name | perl -lne 'chomp; /.*?-(\d+.*?)\z/g;print $1'
            

            【讨论】:

              【解决方案7】:

              你可以对每一行做一个反转,得到最后两个用“-”隔开的元素,然后再反转一次:

              cat "$fl_name"| rev  | cut -f1,2 -d'-' | rev
              

              【讨论】:

                猜你喜欢
                • 2021-02-15
                • 1970-01-01
                • 2011-05-05
                • 1970-01-01
                • 2022-11-16
                • 2023-01-22
                • 2012-07-18
                • 1970-01-01
                • 2014-01-22
                相关资源
                最近更新 更多