【问题标题】:mv Bash Shell Command (on Mac) overwriting files even with a -i?mv Bash Shell 命令(在 Mac 上)即使使用 -i 也会覆盖文件?
【发布时间】:2015-06-21 07:04:27
【问题描述】:

我将嵌套文件夹/图片文件的目录扁平化为单个文件夹。我想将所有嵌套文件移动到根级别。

有 3,381 个文件(计数中不包括目录)。我使用这两个命令计算这个数字并减去目录计数(第二个命令):

find ./ | wc -l
find ./ -type d | wc -l

为了展平,我使用这个命令:

find ./ -mindepth 2 -exec mv -i -v '{}' . \;

问题是,当我在运行 flatten 命令后得到一个计数时,我的计数是 46。在浏览了之前和之后的文件列表之后(我有一个备份),我发现 mv 命令是有时会覆盖文件,即使我使用的是-i。

以下是其中一个文件被覆盖的日志的详细信息...

.//Vacation/CIMG1075.JPG -> ./CIMG1075.JPG
..more log
..more log
..more log
.//dog pics/CIMG1075.JPG -> ./CIMG1075.JPG

所以我可以看到它正在覆盖。我认为-i 应该阻止这种情况。我还尝试了-n 并得到了相同的号码。请注意,我确实有大约 150 个重复的文件名。在我压平所有可能的东西后,我打算手动重命名。

这是时间问题吗? 有办法解决吗?

注意:它提示我某些文件被覆盖。在这些提示上,我只需按Enter 以免覆盖。在上述情况下,没有提示。它只是覆盖。

【问题讨论】:

  • 您使用的是什么版本的 OS X?在 OS X 的早期版本(直到并包括 10.6 Snow Leopard)上,存在一些记录在案的重命名的非原子性问题,这可能是一个因素。
  • 嗨!谢谢回复。我在优胜美地,版本 10.10.2。
  • 最好编写一个脚本来查找重复名称并重命名它们,可能会将路径名嵌入文件中,即Vacation_CIM... 和dog pics_CIM...。由于目录(可能还有文件)名称中有空格,因此您必须忠实地引用所有内容。祝你好运!
  • 您可以使用find . -type f | wc -l 来计算文件名(不包括目录)。是否有任何文件链接或符号链接?我有一台 Mac,但没有重现您在休闲(84 文件)实验中看到的行为。
  • @JonathanLeffler 感谢您的帮助。这就是我的问题 - 符号链接。 :)

标签: macos bash shell


【解决方案1】:

显然manual entry 明确指出:

-n 和 -v 选项是非标准的,不建议在脚本中使用它们。

换句话说,您应该自己模仿-n 选项。为此,只需检查文件是否存在并采取相应措施。在将文件作为第一个参数提供的 shell 脚本中,可以按如下方式完成:

[ -f "${1##*/}" ]

作为第一个参数的文件包含可以使用##*/ 剥离的目录。现在只需使用|| 执行mv,因为我们想在文件不存在时执行。

[ -f "${1##*/}" ] || mv "$1" .

使用它,您可以编辑您的find 命令,如下所示:

find ./ -mindepth 2 -exec bash -c '[ -f "${0##*/}" ] || mv "$0" .' '{}' \;

请注意,由于 bash -c 的用法,我们现在使用 $0。第一个参数$0 不能是脚本名称,因为我们没有脚本。这意味着参数顺序相对于通常的 shell 脚本发生了变化。

【讨论】:

  • 这会奏效的。但它给了我同样的结果,这让我知道我一定做错了什么。发现我有 493 个导致差异的符号链接。感谢您的帮助!
【解决方案2】:

为什么不先检查文件是否存在?然后您可以将文件保留在原处,或者您可以重命名它或执行其他操作...

Test -f 或 [] 应该可以解决问题?

我在平板电脑上,不能轻易包含源代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多