如何重命名文件以包含单引号?

如何重命名文件以包含单引号?

我的 Ubuntu 系统上有多个文件,这些文件分布在 Web 根文件夹中,/var/www但名称已损坏:

GermanyXXXs-enchanting....

我想用撇号 ' 替换 XXX 以获得以下输出:

Germany's-enchanting....

以下命令适用于常规字符,但不适用于引号,即使我转义它:

find /var/www/html -name '*XXX*' -exec bash -c ' mv $0 ${0/XXX/\'}' {} \;

答案1

在类似 Bourne 的 shell 中,单引号字符串中不能有单引号,它们需要以其他方式引用,无论是使用\', "'", $'\''...

另请记住,在 中bash,参数扩展必须至少在列表上下文中(例如在命令的参数中)用双引号引起来。

递归重命名时,还需要确保文件被重命名深度优先并确保仅重命名文件的基本名称部分(而不是目录组件)

find /var/www/html -depth -name '*XXX*' -execdir bash -c '
  ret=0
  for file do
    mv -- "$file" "${file/XXX/\'\''}" || ret=$?
  done
  exit "$ret"' bash {} +

这里引用'\'外部'...'

$file被引用为"$file"在列表上下文中以避免 split+glob。$?不需要引用,因为它是对标量(非列表/数组)变量的赋值,尽管写入ret="$?"不会造成损害。

请注意-execdir(此处使用的$file仅包含基本名称(可能以./某些find实现为前缀))是一个非标准扩展,尽管目前得到了相对广泛的支持。

使用-execdir cmd {} +(+而不是;) 时,某些find实现将在可能的情况下尝试cmd使用多个文件作为参数进行调用,但也许更重要的是,允许在退出状态cmd中报告失败(如果有) 。find

或者您可以使用专门的批量重命名工具。例如,如果使用 zsh 而不是 bash,您可以使用它的zmv自动加载函数:

autoload -Uz zmv
zmv '(**/)(*XXX*)' '$1${2/XXX/'\''}'

Why 会考虑上述所有因素,并事先运行一些健全性检查,以避免丢失数据。

请注意,它会留下隐藏文件。如果你想重命名它们,请将其更改为:

zmv '(**/)(*XXX*)(#qD)' '$1${2/XXX/'\''}'

您可以添加-n选项zmv以进行试运行。

答案2

单引号对中的单引号可以通过关闭单引号、输入\'、然后重新启动单引号对来转义

echo 'It isn't hard'     # broken
echo 'It isn'\''t hard'  # fixed

它将一根断弦变成三个单位'It isn'\''t hard'。另一种思考方式:单引号'中的每个字符都'...'必须替换为'\''

相关内容