由于我犯了一个愚蠢的错误,我刚刚丢失了一小部分音频收藏。 :-(
很高兴我有一个最近的备份,但它仍然令人恼火。除了你真正的备份之外,另一个造成恶作剧的罪魁祸首是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 是否仍然需要为自己编写一个“ mv
scriptlet”以避免这些最不想要的意外。
答案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
在命令行上执行。
这是一种保守的策略,但我经常被错误输入-exec
或sed
命令或误解 shell 扩展所困扰,而且我更喜欢采取缓慢一致的方法。
换句话说:我太胆小了,不敢使用-exec
。