由于我犯的一个愚蠢的错误,我刚刚丢失了我的音频收藏的一小部分。:-( 很
高兴我有一个相当新的备份,但它仍然很烦人。除了你的真实之外,另一个做恶作剧的罪魁祸首是mv,它将显示如下:
音频文件有一定的方案:
ARTIST - Some Title YY.mp3
Run Code Online (Sandbox Code Playgroud)
其中YY是 2 位数年份规范。
mkdir 90<invisible control character>
Run Code Online (Sandbox Code Playgroud)
(直到此刻,我都不知道我实际上输入了三分之一看不见的多余字符......!)
我希望将所有 1990 年代的音乐都放在一个目录中,而不是将所有内容都放在一个目录中。所以我输入:
find . -name '* 9?.mp3' -exec mv {} 90 \;
Run Code Online (Sandbox Code Playgroud)
不难明白发生了什么,嗯?:->
(灾难性的)结果是一个名为“90 something ”的原始空目录(某些东西是“隐形”控制字符)和一个名为“90”的单个文件,被覆盖了n次。
所有文件都不见了。:-(( (明显地)
Wishmv会及时检查目标“文件”的签名(请记住 *NIX: Everything Is A File)是否以d------(例如drwxr-xr-x)开头。而且,当然,目的地是否存在。有上述情况下,当你只是一个变种忘到mkdir的目录第一。(当然,你假设它在那里......)
甚至我们以大写字母W开头的讨厌的操作系统也会这样做。如果您要求,甚至会提示您指定目标类型(文件?目录?)。
因此,我想知道我们 *NIXers 是否仍然必须为自己编写一个“mv脚本”来避免这些最不想要的惊喜。
Mar*_*rco 37
/如果要将文件移动到目录,可以将 a 附加到目标。如果目录不存在,您将收到错误消息:
mv somefile somedir/
mv: cannot move ‘somefile’ to ‘somedir/’: Not a directory
Run Code Online (Sandbox Code Playgroud)
如果目录存在,它会将文件移动到该目录中。
Ant*_*hon 20
GNU coreutilsmv已经有一个选项指定您要移动到目录:-t/ --target-directory。如果该选项的参数不存在,mv将抱怨而不是将所有文件移动到相同的文件名。
我会写你的推动者如下:
find . -name '* 9?.mp3' -exec mv -t 90 {} +
Run Code Online (Sandbox Code Playgroud)
请注意使用+代替\;,将尽可能多的文件名连接在一起,从而加快执行速度。
aye*_*kat 10
此外,如果您通常打算避免将来发生意外覆盖,则可以-i选择mv. 我个人想不出任何缺点,如果你
alias mv='mv -i'
Run Code Online (Sandbox Code Playgroud)
如果您随后需要覆盖某些内容,只需传递该-f选项即可。
别名仅在您直接在交互式 shell 中键入命令时才生效,而不适用于通过find. 你可以跑
find . -name '* 9?.mp3' -exec mv -i {} 90 \;
Run Code Online (Sandbox Code Playgroud)
然后,如果您mv试图覆盖现有文件,系统会提示您。
除了上述出色的答案之外,我想澄清一下为什么您没有收到有关是否移动文件的问题。
如果您将一个文件移动到一个新名称,并且该名称不是目录,mv则会将您的文件重命名为新名称。
这里的问题是您曾经对每个文件find执行mv一次,而不是对所有文件执行一次。
相反,如果您已完成mv *90.mp3 90,则将 mv失败并显示“目标文件不是目录”的错误消息。
另一条建议是在键入目标路径时使用制表符完成。它将通过添加/到目标名称来显示目标是否是目录。您还可以使用mv -i询问是否要覆盖现有文件。