反转使用 find 命令进行的文件名更改?

反转使用 find 命令进行的文件名更改?

Find 是一个很棒的实用程序 - 而且用途广泛。我尝试通过向现有文件名添加后缀或前缀来重命名文件。凉爽的。

find -name "*" -exec mv {} {}.yo \;

现在这是我无法理解的部分 -如果必须撤消上述操作,我该怎么办?

编辑 -
我注意到前缀是不可能的 - 有解决这个问题的方法吗?

find  -type f -name "*"  -exec mv {} yu.{} \;
mv: cannot move './o.txt.yu.yu' to 'yu../o.txt.yu.yu': No such file or directory

答案1

find . -depth -name '*.yo' -exec sh -c '
  ret=0
  for file do
    mv -i -- "$file" "${file%.yo}" || ret=$?
  done
  exit "$ret"' sh {} +

这会将所有file.yo文件(任何类型,包括目录,如您用于添加该.yo后缀的命令中的目录)重命名为filewithout .yo.我们正在以深度优先的方式进行操作(在它们所在的分支之前离开),否则如果您重命名dir.yodir第一个,那么当我们重命名dir.yo/file.yo为该名称时dir.yo/file,它将无法工作,因为它dir.yo不再存在。

使用批量重命名时,-depth几乎总是更好,因此始终使用它是一个好习惯,唯一要记住的是它与-prune.

前缀 withmv {} prefix{}不起作用,因为{}包含包含目录组件的完整路径,而您想要将前缀添加到文件名中,因此您需要类似以下内容:

find . -depth -type f -exec sh -c '
  ret=0
  for file do
    dir=${file%/*} name=${file##*/}
    mv -i -- "$file" "$dir/yu.$name" || ret=$?
  done
  exit "$ret"' sh {} +

这次我们-type f只用来重命名常规的文件,排除所有其他类型的文件,包括目录,先进先出,设备,符号链接, ETC。

mmv我建议使用专用的批量重命名工具,例如orzsh的,而不是手动执行此类操作zmv

zsh

autoload -Uz zmv
zmv '(**/)(*).yo(#qD)' '$1$2'       # remove .yo suffix
zmv '(**/)(*)(#qD.)'   '${1}yu.$2'  # add yu. prefix to regular files

(#q...)是为了全局限定符whereD告诉 zmv 也像find默认情况下一样考虑隐藏文件或隐藏目录中的文件,并且.相当于finds -type f

答案2

扭转:

find  -name "*"  -exec mv {} {}.yo \;

一个简单的方法可能是:

首先创建一个脚本“unyo.bash”

#!/usr/bin/env bash
for name in "$@"; do
  mv "$name"  "${name%.yo}"  
done

然后用它来取消你的文件:

find  -name "*.yo"  -print0 | xargs -0 /path/to/unyo.bash

如果你没有“print0”和“xargs -0”,你可能需要一一执行它们(效率低下,因为它每次都会产生一个bash):

find -name "*.yo" -exec /path/to/unyo.bash '{}' \;

答案3

yu../没有这样的文件或目录。

尝试这个

find * -type f -exec echo {} pref_{} \;

*星号 展开到当前目录中的所有文件,不包含 dir,
如果有子目录使用该选项-prune,则不深入到它

还有这样的构造

find -type f -exec bash -c 'echo  $0 ${0%%/*}/pref_${0##*/}' {} \;

但在其中,位置变量从 $0 开始倒计时,即位于{$0 $1 $2 ...} +或的所有文件{$0} \;

因此,文件数量可以如下计算

find -type f -exec bash -c 'echo  $#' 1 {} +

你可以像这样显示所有文件

find -type f -exec bash -c 'echo  $@' 1 {} +

在这里,您可以使用任何不带空格的字符或单词,而不是一个。这将意味着 $0 变量中的另一个附加文件

答案4

现在这是我无法理解的部分 - 如果必须撤消上述操作,我该怎么做?

您可以使用以下命令。

for FILENAME in `find . -name "*.yo"`; do mv "$FILENAME" $(echo "$FILENAME" | sed -e 's/\.[^.]*$//'); done

相关内容