当使用 mv 移动除一个文件之外的所有文件时,如何转义带有破折号的文件名?

当使用 mv 移动除一个文件之外的所有文件时,如何转义带有破折号的文件名?

如何将当前文件夹中的所有文件移动到子文件夹?,删除文件夹中的所有文件而只保留一个的解决办法是:

mv (!dontmovethis) /new/path/

当尝试移动包含破折号的文件时,实现此目的的方法是:

mv -- '-dashie-file-' /new/path/

但什么是正确的解决方案?

  1. 如果/new/path/包含破折号:/new/-dash-path/
  2. 如果dontmovethis包含破折号:-dont-move-this
  3. 两个都。

天真地尝试

mv -v -- (!'file-with-dash') '/new/path/with-dashes/'

生成神秘消息(-v只是为了使其mv更详细):

bash: !'file: event not found

所以这可能是因为bash正在捕获!字符。但是,当退出 bash 时;

mv -v -- (\!'file-with-dash') '/new/path/with-dashes/'
mv -v -- (\\!'file-with-dash') '/new/path/with-dashes/'
mv -v -- (\\\\!'file-with-dash') '/new/path/with-dashes/'
mv -v -- (\!file-with-dash) /new/path/with-dashes/

(只是尝试一些想法,对需要多少层转义感到困惑),所有这些都产生了这样的结果:

bash: syntax error near unexpected token `(' 

这让我相信,mv在应用运算符时,对完整文件名进行转义的方式并不相同!。最后,类似这样的内容:

mv -v \(\!file-with-dash\) '/new/path/with-dashes'
mv -v \(\!'file-with-dash'\) '/new/path/with-dashes'

生成:

mv: cannot stat '(!file-with-dash)': No such file or directory

这意味着正在(被转义太多了mv正在寻找文件字面上地命名(!file-with-dash),而我希望它寻找file-with-dash

顺便说一句,该帖子的第二个答案容易适应;

ls | grep -v dashing-file | xargs mv -t /new/dashing-folder

可立即生效。此方法有一个注意事项:如果有另一个名为 的文件dashing-file-with-evil-secrets(不是实际的dashing-file,因此需要移动),则会被 捕获grep。因此,这不是一个完全正确的解决方案。

我只是想知道顶部答案(这篇文章中的第一个代码块)是否也可以,因为它没有这个警告。还没有找到办法做到这一点。

答案1

ksh 样式扩展 glob 的语法!(pattern)不是(!pattern)

-dashie-file-要排除名为它的单个文件!(-dashie-file-),或者排除全部包含破折号的文件!(*-*),例如

mv !(-dashie-file-) path/to/newdir/

mv !(*-*) path/to/newdir/

你甚至不需要,--因为 shell 排除了有问题的文件 mv看到它们(尽管包括它是一种很好的做法),例如

$ ls
 -dashie-file-   dashing-file-with-evil-secrets  'other file'   somefile

ls然后为了mv说明的目的使用

$ ls !(-dashie-file-)
 dashing-file-with-evil-secrets  'other file'   somefile

$ ls !(*-*)
'other file'   somefile

相关内容