如何防止“mv”将一组文件移动到单个常规文件中?

如何防止“mv”将一组文件移动到单个常规文件中?

由于我犯了一个愚蠢的错误,我刚刚丢失了一小部分音频收藏。 :-(
很高兴我有一个最近的备份,但它仍然令人恼火。除了你真正的备份之外,另一个造成恶作剧的罪魁祸首是mv,它将显示如下:

音频文件有一定的方案:

ARTIST - Some Title YY.mp3

其中YY是 2 位数年份规范。

mkdir 90<invisible control character>

(直到此刻,我还不知道我实际上输入了三分之一多余的字符,这是不可见的......!)
我不想将所有内容都放在一个目录中,而是想将所有 90 年代的音乐放在一个目录中。所以我输入:

find . -name '* 9?.mp3' -exec mv {} 90 \;

不难理解发生了什么吧? :->
(灾难性的)结果是处女空的名为“90”​​的目录某物' (和某物是“看不见的”控制角色)和一个文件称为“90”​​,被覆盖n次。

所有文件都消失了。 :-(( (明显地)

希望mv检查过及时是否对目标“文件”进行签名(记住在 *NIX 上:一切都是文件) 以d------(例如drwxr-xr-x) 开头。当然,无论是目的地存在根本不。上述场景还有一个变体,当您简单地忘记首先到mkdir目录。 (但当然,你假设它在那里......)

就连我们讨厌的操作系统也从大写开始确实这样做。你能扳平提示如果您需要的话,指定目标的类型(文件?目录?)。

因此,我想知道我们 *NIXers 是否仍然需要为自己编写一个“ mvscriptlet”以避免这些最不想要的意外。

答案1

/如果要将文件移动到目录,可以将 a 附加到目标位置。如果该目录不存在,您将收到错误:

mv somefile somedir/
mv: cannot move ‘somefile’ to ‘somedir/’: Not a directory

如果该目录存在,它将文件移动到该目录中。

答案2

GNU coreutilsmv已经有一个选项指定您要移动到目录:-t/ --target-directory。如果该选项的参数不存在,mv则会抱怨,而不是将所有文件移动到相同的文件名。

我会把你的搬运工写成如下:

find . -name '* 9?.mp3' -exec mv -t 90 {} +

请注意使用+代替\;,将尽可能多的文件名组合在一起,从而加快执行速度。

答案3

此外,如果您通常计划避免将来意外覆盖,则可以-i选择mv.我个人认为如果你

alias mv='mv -i'

如果您需要覆盖某些内容,只需传递该-f选项即可。

仅当您直接在交互式 shell 中键入命令时,别名才会生效,而对于通过find.你本来可以跑

find . -name '* 9?.mp3' -exec mv -i {} 90 \;

然后系统会提示您是否mv尝试覆盖现有文件。

答案4

作为替代的通用策略,我建议将这种操作转变为临时脚本。我更喜欢查看结果find并将其手动转换为mv命令,以确保在执行之前了解我在做什么。例如。

find . -name '* 9?.mp3' > tmp
vim tmp

现在我可以查看文件名列表并将文件内容重写为 shell 命令。

  • 将文件内容放在一行上:ggVGJ
  • 前置:Imv [esc]
  • 附加:Asomedir/ [esc]
  • 保存文件。再读一遍。喘口气。
  • source tmp在命令行上执行。

这是一种保守的策略,但我经常被错误输入-execsed命令或误解 shell 扩展所困扰,而且我更喜欢采取缓慢一致的方法。

换句话说:我太胆小了,不敢使用-exec

相关内容