【问题标题】:change date format from DD/MM/YYYY to YYYY-MM-DD with sed使用 sed 将日期格式从 DD/MM/YYYY 更改为 YYYY-MM-DD
【发布时间】:2019-02-17 14:43:41
【问题描述】:

我在做:

sed -e 's|\([0-9][0-9]\)/\([0-2][0-9]\)/\([0-9][0-9][0-9][0-9]\)|\3-\2-\1|g' 

但是当我运行程序时,我得到了这个错误:

"sed: -e expression #4, char 62: invalid reference \3 on `s' command's RHS"

【问题讨论】:

    标签: bash date sed format


    【解决方案1】:

    这个错误一般发生在捕获组没有被正确转义的时候。

    也就是说,捕获组的括号在您的命令中进行了转义,因此您可能尝试将它与 Extended Regular Expressions 标志(sed -rsed -E)一起使用,以防万一不需要逃避它。

    请注意,为了便于阅读,您可以将字符范围与数字量词结合使用:

    sed -E "s|([0-9]{2})/([0-9]{2})/([0-9]{4})|\3-\2-\1|" file
    

    【讨论】:

      【解决方案2】:

      因为有括号,你需要添加\ 使其作为组捕获:

      echo 03/11/2018|sed -e 's|\([0-9][0-9]\)/\([0-2][0-9]\)/\([0-9][0-9][0-9][0-9]\)|\3-\2-\1|g'
      2018-11-03
      

      在某些 sed 版本如 GNU sed 中,可以添加 -E-r 开关,然后转义将变为相反的方式:

      echo 03/11/2018|sed -E 's|([0-9][0-9])/([0-2][0-9])/([0-9][0-9][0-9][0-9])|\3-\2-\1|g'
      2018-11-03
      

      默认情况下,您需要使用\(....\) 将事物分组,() 将按字面意思匹配括号。
      但是,使用-E-r 开关,(...) 可以捕获组,\(\) 可以从字面上匹配括号。
      顺便说一句,{}() 的情况一样。

      【讨论】:

        【解决方案3】:

        请您尝试关注一下。

        echo "xxx 03/11/2018" |
        awk  '
         match($0,/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9]/){
           if(RSTART!=1){
             val=substr($0,1,RSTART-1)
           }
           val=val substr($0,RSTART+6,4)"/"substr($0,RSTART+3,2)"/"substr($0,RSTART,2)
           print val substr($0,RSTART+RLENGTH)
        }'
        

        说明:现在为上述代码添加说明。

        echo "xxx 03/11/2018" |                                                               ##Using echo command for printing string and passing its output into awk command.
        awk  '                                                                                ##Starting awk program here.
         match($0,/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9]/){                            ##Using match function for matching regex 2 digits / 2 digits / 4 digits.
           if(RSTART!=1){                                                                     ##Checking if RSTART is NOT equal to 1 then do following.
             val=substr($0,1,RSTART-1)                                                        ##Creating variable val whose value is substring from 1 to RSTART-1, RSTART and RLENGTH are variables which will be SET once a match of regex is found bymatch function of awk.
           }                                                                                  ##Closing block of if condition here.
           val=val substr($0,RSTART+6,4)"/"substr($0,RSTART+3,2)"/"substr($0,RSTART,2)        ##Creating variable val here as per OPs need YYYY/MM/DD by using substring and its index values changing.
           print val substr($0,RSTART+RLENGTH)                                                ##Printing value of variable val and substring from value of RSTART+RLENGTH to till end of line.
        }'                                                                                    ##Closing block of match now.
        

        这也将处理匹配日期的文本之前和之后。就像上面的例子一样,我添加了xxx,它会在日期之前出现,如下所示。

        xxx 2018/11/03 
        


        或者,如果您想打印其他行以及 YYYY/MM/DDlines,请尝试关注。

        echo "xxx 03/11/2018" |
        awk  '
         match($0,/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9]/){
           if(RSTART!=1){
             val=substr($0,1,RSTART-1)
           }
           val=val substr($0,RSTART+6,4)"/"substr($0,RSTART+3,2)"/"substr($0,RSTART,2)
           print val substr($0,RSTART+RLENGTH)
           next
        }
        1 '
        

        注意: 由于我的awk 版本较旧,所以我使用match($0,/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9]/,但如果您的awk 是新的,我相信您可以使用match($0,/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/)版本。

        【讨论】:

        • @Luis Valdes,如果这对你有帮助,请告诉我吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-29
        相关资源
        最近更新 更多