如何将文件扩展名数字加一

如何将文件扩展名数字加一

在以下当前文件夹下,我们有文件示例

lok.log.1
df.log.6
weq.log.90
vr.log.11
vs.aw.frsd.log.3

我们想将文件扩展名增加 1

所以预期的输出如下

lok.log.2
df.log.7
weq.log.91
vr.log.12
vs.aw.frsd.log.4

请建议如何使用查找和正则表达式重命名文件

  • 这个概念应该是所有具有“.log”的文件将被重命名为+1

答案1

zsh

autoload zmv # best in ~/.zshrc
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'

-n(如果对结果满意则删除)

  • <->匹配任何十进制数
  • (#qnOn)n: glob 限定符此处按名称 () 以相反顺序按数字 ( On)对文件列表进行排序,因此file.log.2重命名为file.log.3beforefile.log.1重命名为file.log.2..如果您只想重命名,请添加常规的文件(但如果您还想重命名隐藏文件,您可能需要添加一个-o-nT假设 GNU 的选项mv) 。D
  • -f当文件被重命名为现有文件时,禁用会取消该命令的保护措施,这会妨碍我们上面的示例file.log.1file.log.2它仍然会防范两者foo.log.1并被foo.log.01重命名为foo.log.2.

递归地:

zmv -n -f '(**/)(*.log.)(<->)(#qnOn)' '$1$2$(($3+1))'

来自bashshksh:

zsh << 'EOF'
autoload zmv
zmv -n -f '(*.log.)(<->)(#qnOn)' '$1$(($2+1))'
EOF

无论bash是否使用 using zsh,如果您有 GNUls和 GNU mv,并且文件列表不是太大,您可以执行以下操作:

shopt -s failglob
shopt -s extglob
export LC_ALL=C
eval "files=($(
  ls --quoting-style=shell-always -rvd -- *.log.+([[:digit:]])))"
for f in "${files[@]}"; do
   echo mv -nT -- "$f" "${f%.*}.$((10#${f##*.} + 1))"
done

(满意后移除echo)。

递归地,使用 GNU bash、 GNU find、 GNUmv和 GNU sort,仅适用于常规文件:

export LC_ALL=C
while IFS= read -rd '' -u3 file; do
  echo mv -nT "$file" "${file%.*}.$((10#${file##*.} + 1))"
done 3< <(
  find . -name '.?*' -prune -o -regex '.*\.log\.[0-9]+' -type f -print0 |
    sort -rzV)

mv -n是一个 GNU 扩展,以避免破坏现有文件,并-T消除之间的歧义搬去搬进否则mv会受到影响。但请注意,当文件因 原因而未重命名时-n,您不会收到任何相关错误。

答案2

rename基于- 并允许使用算术(某些发行版使用此重命名工具的perl名称):prenameperl

rename 's/(log.)([0-9]+)$/$1.($2+1)/e' <files>

要与 find 结合使用,请使用:

find <search options> -exec rename 's/(log.)([0-9]+)$/$1.($2+1)/e' {} +

编辑以下 Stéphane 的评论:

未排序的输出find可能确实会给您带来麻烦,最好事先对其进行排序。我们可以对给定的名称模式使用反向 (!) 排序及其版本编号选项:

find <search parpameters> -print0 |\
   sort -rzV |\
   xargs -r0 rename 's/(log.)([0-9]+)$/$1.($2+1)/e'

相关内容