【问题标题】:Set file modification time from the date string present in the filename根据文件名中存在的日期字符串设置文件修改时间
【发布时间】:2019-04-20 06:11:19
【问题描述】:

我正在恢复一些名称中带有日期的档案,类似于:

user-2018.12.20.tar.xz
user-2019.01.10.tar.xz
user-2019.02.25.tar.xz
user-2019.04.19.tar.xz
...

我想设置每个文件的修改日期以匹配文件名中的日期,方法是将文件名通过xargs 传送到touch 并使用replace-str 设置日期。

touch -m -t 将采用 [CCYYMMDDhhmm] 格式的日期时间,但我无法替换内联:

find . -name "*.xz" | xargs -I {} touch -m -t $(sed -e 's/\.tar\.xz//g; s/user-//g; s/\.//g; s/\///g; s/$/0000/g' {}) {}

返回touch: invalid date format ‘./user-2018.03.22.tar.xz’,即使这样:

find . -name "*.xz" | sed -e 's/\.tar\.xz//g; s/user-//g; s/\.//g; s/\///g; s/$/0000/g'

返回格式正确的日期,例如201812200000。我是否以某种方式在替换字符串中滥用了命令替换?

编辑: 是的,一个简单的脚本可以做到这一点没有问题。但问题仍然存在......

【问题讨论】:

    标签: linux bash shell sed xargs


    【解决方案1】:

    您不需要findsedxargs 或任何第三方工具,只需使用shell 内置的正则表达式功能从文件中获取时间戳

     for file in *.tar.xz; do
         [ -f "$file" ] || continue
         if [[ $file =~ ^user-([[:digit:]]+).([[:digit:]]+).([[:digit:]]+).tar.xz$ ]]; then
             dateStr="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}0000"
             touch -m -t "$dateStr"
         fi
     done
    

    【讨论】:

      【解决方案2】:

      问题在于,当您调用xargs 时,命令替换将被评估一次,而不是针对每个参数。您需要为此生成一个外壳:

      find . -name "*.xz" \
        | xargs -I {} bash -c 'touch -m --date "$(sed -e "s/\.tar\.xz//;s/user-//g; s/\.//g; s/\///g;" <<< "$1")" "$1"' -- {}
      

      注意:不需要xargs,因为您可以使用find-exec 选项:

      find . -name "*.xz" -exec bash -c 'touch -m --date "$(sed -e "s/\.tar\.xz//;s/user-//g; s/\.//g; s/\///g;" <<< "$1")" "$1"' -- {} \;
      

      PS:小的 for 循环会更易读:

      for file in user-*.tar.xz ; do
          # remove prefix and suffix
          date=${file#user-}
          date=${date%.tar.xz}
          # replace dots by /
          date=${date//./\/}
      
          touch -m --date "${date}" "${file}"
      done
      

      【讨论】:

        【解决方案3】:

        这可能对你有用(GNU 并行):

        parallel --dryrun touch -m --date '{= s/[^0-9]//g =}' {} ::: *.xz
        

        如果对命令正确感到满意,则删除 --dryrun 选项。

        替代方案:

        parallel touch -m --date `{= s/user-//;s/\.tar\.xz//;s/\.//g =}' {} ::: *.xz
        

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多