【问题标题】:Replace double quotes alongside other invalid windows filename characters in filenames on linux在Linux上的文件名中替换双引号以及其他无效的Windows文件名字符
【发布时间】:2017-02-20 07:20:19
【问题描述】:

我在 ubuntu 14.04 linux 机器上的文件在目录中包含无效的 windows 字符,例如 ?:"|* 等。我希望删除这些无效的 windows 字符,以便可以从 windows 机器上查看它们也是。

例如:以下是目录中的几个文件:

file "1".html
file "asdf".txt

重命名后的预期输出应该是:(本质上,它用单个下划线重命名无效字符)

file _1_.html
file _asdf_.txt

我一直在运行来自Find files with illegal windows characters in the name on Linux 的命令(稍作修改):

find . -name "*[<>\\|?:\"*]*" -exec bash -c 'x="{}"; y=$(sed "s/[<>\\|?:\"*]\+/_/g" <<< "$x") && echo "renaming" "$x" "-->" "$y" && mv "$x" "$y" ' \;

但是,上面的 bash 命令对包含双引号的文件失败。它适用于其他无效字符。

你能帮忙修复这个脚本吗?提前致谢。

【问题讨论】:

  • 有一个名为 rename 的实用程序(不幸的是,实际上是两个)应该可以轻松完成任务。
  • 我希望修改这个脚本。我不介意使用重命名,除非这个脚本无法工作。不过,感谢您提及重命名。

标签: regex linux bash sed find


【解决方案1】:

使用bashparameter expansion

$ touch 'file "1".html' 'file "asdf".txt' 'a<b' 'f?r' 'e*w' 'z|e' 'w:r' 'b>a'

$ ls
a<b  b>a  e*w  file "1".html  file "asdf".txt  f?r  w:r  z|e

$ find -name "*[<>\\|?:\"*]*" -exec bash -c 'echo mv "$0" "${0//[<>\\|?:\"*]/_}"' {} \;
mv ./z|e ./z_e
mv ./file "asdf".txt ./file _asdf_.txt
mv ./a<b ./a_b
mv ./file "1".html ./file _1_.html
mv ./e*w ./e_w
mv ./w:r ./w_r
mv ./f?r ./f_r
mv ./b>a ./b_a

$ find -name "*[<>\\|?:\"*]*" -exec bash -c 'mv "$0" "${0//[<>\\|?:\"*]/_}"' {} \;
$ ls
a_b  b_a  e_w  file _1_.html  file _asdf_.txt  f_r  w_r  z_e


使用extglob

$ touch 'tmp::<>|asdf.txt'
$ find -name "*[<>\\|?:\"*]*" -exec bash -c 'shopt -s extglob; echo mv "$0" "${0//+([<>\\|?:\"*])/_}"' {} \;
mv ./tmp::<>|asdf.txt ./tmp_asdf.txt


perl为基础的rename

$ find -name "*[<>\\|?:\"*]*" -exec rename 's/[<>\\|?:\"*]/_/g' {} +
$ ls
a_b  b_a  e_w  file _1_.html  file _asdf_.txt  f_r  w_r  z_e

使用rename -n 进行试运行而不实际重命名文件

$ touch 'tmp::<>|asdf.txt'
$ find -name "*[<>\\|?:\"*]*" -exec rename -n 's/[<>\\|?:\"*]+/_/g' {} +
rename(./tmp::<>|asdf.txt, ./tmp_asdf.txt)

【讨论】:

  • 知道如何使用基于 bash 参数扩展的答案来扩展“mv”,以将多个连续出现的无效字符替换为单个 _,就像在之前的 sed 脚本中所做的那样?例如,tmp::&lt;&gt;|asdf.txttmp_asdf.txt。这在以前的基于 sed 的脚本中运行良好。我正在运行 GNU bash 4.3.11,我尝试运行 shopt -s extglob,然后运行 ​​find -name "*[&lt;&gt;\\|?:\"*]*" -exec bash -c 'echo renaming "$0" "--&gt;" "${0//+([&lt;&gt;\\|?:\"*])/_}"' {} \;,这似乎没有产生预期的结果
  • 似乎我们需要在bash -c 脚本中设置shopt -s extglob... 将编辑答案
  • 感谢您提供基于 perl 的重命名答案。修改它以用单个 _ 替换多个连续出现的内容非常容易
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多