在Linux上查找文件名中包含非法Windows字符的文件

13

我在Linux系统上有一个项目,其中包含一些在Windows系统中被认为是非法/保留的字符(详见http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx),这个项目跨越多个文件夹有超过10,000个文件,我想要找到这些文件的路径。

我可以使用find . -name "*\?*"命令查找每个非法/保留字符,但是否有更简便的方法可以查找包含以下字符的所有文件:< > : " / \ | ? *

一旦找到这些文件,我希望从它们的内容中删除所有此类字符。

3个回答

18

这个单行代码应该适用于你:

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

Anubhava,我能否将mv应用于文件夹? - Rohit Chopra
我相信上述命令可以同时针对文件和文件夹执行此操作。 - anubhava
太棒了。非常感谢。还有一个问题,如果您不介意的话。是否可以链接一些内容到此命令,以便它也更新HTML文件中对这些文件的引用。换句话说,如果一个HTML文件引用“/inc/test:512?abc”,而这个命令将名称更改为“/inc/test-512-abc”,那么也要将HTML文件中的出现更改为新的吗?很抱歉文字有点长,非常感谢您的帮助。 - Rohit Chopra
您可以使用以下命令运行单独的查找:**find . -type f -name '*.html' -exec sed -i.bak 's/[<>:\\|?*]\+/-/g' '{}' \;** - anubhava
1
这个一行代码非常好用,可以在文件和文件夹中查找和替换无效字符。我有很多从Mac备份到NTFS格式的外部硬盘中的目录和文件。在Windows 10中它们真的是一个问题,直到使用了你的解决方案,所以谢谢!我唯一能提供给Linux新手的提示是使用带引号但不带括号的(cd "your drive / folder path")。我一直无法让终端切换到我的外部驱动器路径,直到我使用了引号。 - Coby Randal
显示剩余6条评论

17

fnmatch模式允许您在[]中指定如下的字符:

find . -name '*[<>:/\\|?*]*'

谢谢!我能否将xargs命令链接起来重命名这些文件,删除那些字符并用破折号替换它们? - Rohit Chopra
1
我必须将双引号更改为单引号才能找到反斜杠。 - wjandrea
@wjandrea,感谢您的反馈。我已根据您的意见更新了代码。 - falsetru
1
我必须将双引号添加为搜索项。因此,我用单引号替换了双引号,然后添加了双引号作为搜索项。 - Ioannis Iliadis aka Ilousis
双引号是我服务器上最大的问题... 其次是时间格式,例如 "Resume" 12:00pm.docx - Ray Foss
这个警告信息是“find: warning: ‘-name’ matches against basenames only, but the given pattern contains a directory separator (‘/’), thus the expression will evaluate to false all the time. Did you mean ‘-wholename’?”,但程序似乎正常工作。 - CervEd

6

以上两个答案都无法找到以空格 (' ') 或点/句号 ('.') 结尾的文件或目录,这些文件在使用 Win32 API 也无法看到。

除了 @falsetru 的答案之外,还可以执行以下操作:

find . -name '*[<>:/\\|?*]*' -o -name '*[ \.]'

1
尽管它们不可见,但我猜它们在文件系统层面上仍然是有效的字符。这可能是一个问题,也可能不是。 - CervEd
它找到了文件,但是你如何将它们串起来,用有效的字符替换那些无效的字符呢? - Coby Randal
@Coby-Randal。类似于“find ... -print0 | xargs -0 <cmd>”这样的命令。 - HASM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接