【问题标题】:Use [msys] bash to remove all files whose name matches a pattern, regardless of file-name letter-case使用 [msys] bash 删除名称与模式匹配的所有文件,无论文件名字母大小写如何
【发布时间】:2015-02-26 03:53:57
【问题描述】:

我需要一种清理目录的方法,该目录由 (1) 一些工具生成的 C/C++ 内置文件(.o、.a、.EXE、.OBJ、.LIB 等)填充始终创建具有大写名称的文件,以及 (2) 始终创建小写文件名的其他工具。 (我无法控制这些工具。)

我需要通过 MinGW 'msys' bash.exe shell 脚本(或 bash 命令提示符)执行此操作。我理解管道(|),但还没有想出正确的 exec 组合。我已经成功过滤了文件名,使用如下示例的命令:

ls | grep '.\.[eE][xX][eE]'

列出在文件扩展名中具有任何大小写字母组合的所有文件——本示例获取所有可执行文件(例如“.EXE”)。

(我会为 .o、.a、.OBJ、.LIB、.lib、.MAP 等做类似的事情,它们都与 C/C++ 源文件共享同一个目录。我不想删除源文件,只删除内置文件。是的,我可能应该重新设计目录结构,为内置文件使用单独的目录[仅],但这需要时间,我需要一个快速的解决方案现在。)

我怎样才能将上述命令与其他“东西”合并(例如,像“rm -f”命令???),更进一步,实际删除[仅]那些过滤掉的文件从当前目录? (我希望有一个不需要临时文件来保存过滤后的文件名的解决方案。)

【问题讨论】:

  • find /path/to/some/directory -iname '*.exe' -delete
  • 我应该注意到问题描述中的一个小错误:“ls | grep '.*\.[eE][xX][eE]'” 实际上是获取 ALL 所需的命令.exe”文件名(我在正则表达式中添加了一个“*”来跟随“匹配任何字符”“。”)。 (我最初只匹配单字符文件名,例如“t.exe”。)
  • grep '.\.[eE][xX][eE]' 将匹配 grep '.*\.[eE][xX][eE]' 匹配的任何内容。尽可能使用grep '.' in place of grep '..*'

标签: c++ linux bash shell


【解决方案1】:

添加此答案是因为接受的答案是建议在实际脚本中不推荐的做法。 (请不要难过,我也去过那条赛道..)

解析 ls 输出是不可以的!有关原因的更详细说明,请参阅http://mywiki.wooledge.org/ParsingLs

简而言之,ls 用换行符分隔文件名;它可以存在于文件名本身中。 (另外,ls 不能正确处理其他特殊字符。ls人类 可读的形式打印输出。)在 unix/linux 中,文件名中有换行符是完全有效的。

但 unix 文件名不能有 NULL 字符。因此下面的命令应该可以工作。

find /path/to/some/directory -iname '*.exe' -print0 | xargs -0 rm -f
  1. find: 是一种用于查找与所需模式/标准匹配的文件的工具。
  2. -iname:使用特定名称搜索,不区分大小写。请注意,-iname 的参数是通配符,而不是正则表达式。
  3. -print0:打印以NULL字符分隔的文件名。

  4. xargs:从标准输入获取输入并在它们上运行提供的命令(在本例中为rm -f)。默认情况下,输入以空格分隔。

  5. -0 指定输入以空字符分隔。

甚至更好的方法,

find /path/to/some/directory -iname '*.exe' -delete

-delete 是 find 的内置功能,它会删除找到的带有模式的文件。

请注意,如果您想做一些其他操作,例如将它们移动到特定目录,您需要使用 xargs 的第一个选项。

最后,这个命令find /path/to/some/directory -iname '*.exe' -delete 将递归地找到*.exe 文件/目录。您可以使用-maxdepth 1 将搜索限制在当前目录,并将文件类型限制为使用-type f 的简单文件(不是目录、管道等)。查看我提供的手动链接以获取更多详细信息。

【讨论】:

    【解决方案2】:

    这就是你的意思?

    rm -f `ls | grep '.\.[eE][xX][eE]'`
    

    但通常您的“ls | grep ...”输出将包含一些您必须删除的其他字段,例如日期等,因此您可能只想输出文件名本身。

    尝试类似:

    rm -f `ls | grep '.\.[eE][xX][eE]' | awk '{print $9}'`
    

    您的文件名在第 9 个字段中,例如:

    -rwxr-xr-x  1 Administrators None       283 Jul  2  2014 search.exe
    

    【讨论】:

      【解决方案3】:

      您可以使用以下命令:

      ls | grep '.\.[eE][xX][eE]' | xargs rm -f
      

      使用“xargs”会将标准输入(在本例中为上一个命令的输出)作为“rm -f”命令的参数。

      【讨论】:

      • 谢谢,我不知道 xargs。我自己找到了一种更简单的方法,尽管它不使用 grep: rm -f ./*.[eE][xX][eE]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 2020-12-23
      相关资源
      最近更新 更多