3

我正在复习考试,其中一个问题是要求我编写一个命令,该命令将删除给定目录中至少 6 个字符长的文件。

例子:

人@ubuntumachine:~$ ls

abc.txt, abcdef.txt, 123456.txt, helloworld.txt, rawr.txt

该命令将删除文件“abcdef.txt”、“12346.txt”和“helloworld.txt”。

我知道 at * 会在某些时候使用,但我不确定用什么来表示 6 个字符长...

谢谢<3

4

3 回答 3

18

由于该问题可以有两种解释,因此给出了两个答案:

1. 删除文件名中包含 6 个或更多字符的文件:

rm ??????*

解释:

  • ??????: ?'s 将按字面意思输入。每个?匹配任何单个字符。所以这里的意思是“匹配任意 6 个字符”
  • *:*通配符匹配零个或多个字符
  • 因此,它会删除任何包含 6 个或更多字符的文件。

或者:

find -type f -name "??????*" -delete

解释:

  • find: 调用 find 命令
  • -type f: 只查找文件。
  • -name "??????*": 匹配任何至少 6 个字符的文件,与上面的想法相同。
  • -delete:删除找到的任何此类文件。

2. 删除 CONTENTS 中包含 6 个或更多字符的文件:

find -type f -size +5c -delete

说明

  • find: 调用 find 命令
  • -type f:只查找文件(不查找目录等)
  • -size +5c: 只查找长度大于 5 个字符的文件。注意:请记住,EOF在这种情况下,(文件结尾)算作一个字符。如果您想EOF从计数器中排除,请将其从 5 更改为 6。
  • -delete:删除找到的任何此类文件
于 2012-11-16T02:27:57.767 回答
2

像这样的东西应该工作:

$ ls|while read filename; do test ${#filename} -gt 6 && echo rm "$filename"; done

诀窍是使用${#foo}构造来获取文件名的长度。

对输出感到满意后,立即在上一个命令之后运行以下命令:

$ !! | sh

这会重复最后一个命令(显示删除文件的 rm 命令)并将其通过管道传递给 sh 以真正执行它。

于 2012-11-16T02:27:49.797 回答
0

这将对当前目录和所有子目录执行请求的逻辑。

find . -type f -regextype posix-egrep -regex ".*/[^/]{5}[^/]+$" -exec rm -vf {} \;

  • find .
    • 搜索本地目录(将 . 更改为在别处搜索)
  • -type f
    • 只考虑文件
  • -regextype posix-egrep
    • 使用 egrep 正则表达式语法(这是我所知道的)
  • -regex ".*/[^/]{5}[^/]+$"
    • find 将匹配与此正则表达式匹配的所有路径
    • 正则表达式解构如下:
      • .*/有效地忽略路径,直到文件名
      • [^/]{5}找到 5 个不是斜杠的字符
      • [^/]+$ 需要在行尾 ($) 之前出现至少一个非斜杠的字符(因此:6 个或更多)
  • -exec rm -vf {} \;
    • find 将用{}其搜索查询匹配的每个文件替换 (在这种情况下,文件的路径与我们的正则表达式匹配)。这样就实现了删除。 -vf添加以打印结果,以便您知道发生了什么。
      • -exec对语法很挑剔 -如果在其位置使用简单,\;则必须避免find: missing argument to '-exec'遇到这种情况。;
      • 您可以通过使用-print而不是-exec rm -vf {} \;或简单地删除-exec rm -vf {} \;(-print是 find 的默认行为)来测试它
于 2012-11-16T03:10:01.897 回答