我正在还原一些名称中带有日期的档案,大致类似于:
user-2018.12.20.tar.xz
user-2019.01.10.tar.xz
user-2019.02.25.tar.xz
user-2019.04.19.tar.xz
...
我想通过touch
将文件名传递到xargs
并使用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
。我是否会以某种方式在替换字符串中滥用命令替换?
编辑:是的,简单的脚本可以做到这一点。但是问题仍然存在...
答案 0 :(得分:4)
您不需要find
,sed
,xargs
或任何第三方工具,而只需使用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
答案 1 :(得分:4)
问题在于,当您调用xargs
时,命令替换将被评估一次,而不是针对每个参数。您需要为此生成一个shell:
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
,因为您可以使用-exec
的{{1}}选项:
find
PS:一个小的for循环将更具可读性:
find . -name "*.xz" -exec bash -c 'touch -m --date "$(sed -e "s/\.tar\.xz//;s/user-//g; s/\.//g; s/\///g;" <<< "$1")" "$1"' -- {} \;
答案 2 :(得分: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