linux - 如果不是当前文件,则重命名文件

标签 linux bash shell

我对 bash 脚本编写还很陌生。我正在尝试编写一行来搜索具有特定名称的所有文件,并重命名它们,当前正在运行的脚本除外。

这是我目前所拥有的:

find $1 -name thescript.sh -exec /bin/bash -c 'test \'"$(readlink -f "$0")" = {}\' || mv {} \$\(dirname {}\)/thescript0.sh' \; || true

这里简要解释一下它在我脑海中是如何工作的:

  • 使用 readlink 确定当前运行脚本的绝对路径
  • 对于所有文件 {}名为 thescript.sh$1 的某个子目录中:
    • 测试生成的绝对路径是否等于文件 {}
    • 如果测试失败(即它们不相等):
      • 确定文件的目录{}
      • 移动文件{}到同一目录下但名称为 thescript0.sh 的文件
  • 总是返回真

一些注意事项:

  • $1脚本的第一个参数是重命名的基本目录
  • 因为我想在 || 中使用“或”( exec )子句,我遵循了对 this question 的一些回答并使用引用的命令启动了一个新的 shell,我可以在其中使用 || ,这样 shell 就不会认为这个运算符是父命令的一部分。引用的命令从 test 开始结束于 thescript0.sh
  • readlink在子 shell 中,因为 readlink 的结果传递给 test
  • 我对 test 使用了转义引号因为否则我认为 shell 会认为第一个引号实际上是前一个单引号的终止符(它启动了引用的命令)
  • 我也逃脱了 subshel​​l,不确定这是否正确(我还没有做到这一点),因为我希望 subshel​​l 根据 find 的输出作为引用命令的一部分执行。 , 而不是在开始时执行(当它还没有输出可以处理时)
  • 如果测试失败(在大多数情况下是预期的),那么我不希望整个命令返回 false(不确定是否会),所以这就是我输入 || true 的原因最后

我得到的错误是:

line 15: unexpected EOF while looking for matching `''

目前我找不到任何不匹配的报价;只有一对未转义的引号。

最佳答案

单引号不接受任何转义序列,甚至 \' 也不接受。要在单引号字符串中包含单引号,您必须离开并重新输入:

echo 'What'"'"'s wrong?'
echo 'Oh, it'\''s nothing.'

补充说明:

  • $0 不会在单引号内展开。

  • find的退出代码与-exec的结果无关,所以||不需要 true

  • 为了最大程度的安全,最好将 {} 作为参数传递给 bash,而不是将其嵌入脚本中。这样空格和其他特殊字符就不会绊倒 bash。

  • 始终引用变量扩展以防它们包含空格或通配符。

考虑到以上所有因素,我推荐的更新:

find "$1" -name thescript.sh -exec bash -c 'test "$1" == "$2" || mv "$2" "$(dirname "$2")"/thescript0.sh' bash "$(readlink -f "$0")" {} \;

(我还没有测试过,所以希望你能理解要点,即使我打错了一些字。)

关于linux - 如果不是当前文件,则重命名文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48430892/

相关文章:

c - 如果没有预先 ping 则 UDP 数据包不会到达

c - 如何让线程休眠/阻塞纳秒(或至少毫秒)?

linux - 为什么我的 bash 脚本不能正确运行?

linux - 如何通过 grep 响应找出有多少调用超时?

python - 无法运行原始 git filter-branch

linux - 带有 Wget 的 Shell 脚本 - 如果 else 嵌套在 for 循环中

c - 在 Linux 中操作 u64 类型

bash - 无法在 elementary os loki 中设置 GOPATH

linux - 我想读取第一行值并从第二行值中减去它并继续直到结束

linux - 在 Linux 中使用 -sort