查找包含linux中包含关键字的文件的所有目录

时间:2014-07-14 13:02:28

标签: linux shell directory find

在我的目录层次结构中,我有许多名为STATUS.txt的文本文件。这些文本文件每个都包含一个关键字,如COMPLETE,WAITING,FUTURE或OPEN。我希望执行以下形式的shell命令:

./mycommand OPEN

将列出包含名为STATUS.txt的文件的所有目录,其中此文件包含文本" OPEN"

将来我会想要扩展这个脚本,以便对返回的目录进行排序。排序将由存储在PRIORITY.txt文件中的数值确定,该文件与STATUS.txt位于相同的目录中。但是,这可以等到我的能力水平提高。目前我很乐意按任意顺序列出目录。


我搜索了Stack Overflow以下内容,但无济于事:

  • 按文件内容过滤unix
  • linux按文件内容过滤
  • shell遍历目录文件内容
  • bash遍历目录文件内容
  • shell遍历目录查找
  • bash遍历目录查找
  • linux文件内容目录
  • unix文件内容目录
  • linux查找名称内容
  • unix查找名称内容
  • shell读取文件显示目录
  • bash读取文件显示目录
  • bash目录搜索
  • shell目录搜索

我尝试了以下shell命令:

这有助于我识别包含STATUS.txt的所有目录

$ find ./ -name STATUS.txt

这将为包含它的每个目录读取STATUS.txt

$ find ./ -name STATUS.txt | xargs -I{} cat {}

这不会返回任何文本,我希望它会返回每个目录的名称

$ find . -type d | while read d; do if [ -f STATUS.txt ]; then echo "${d}"; fi; done

5 个答案:

答案 0 :(得分:4)

也许你可以试试这个:

grep -rl "OPEN" . --include='STATUS.txt'| sed 's/STATUS.txt//'

其中grep -r表示递归,-l表示只列出匹配的文件,'。'是目录位置。您可以将其传输到sed以删除文件名。

然后,您可以将其打包在一个bash脚本文件中,您可以在其中传递' OPEN',' FUTURE'等关键字。作为一个论点。

#!/bin/bash
grep -rl "$1" . --include='STATUS.txt'| sed 's/STATUS.txt//'

答案 1 :(得分:3)

......或者相反:

find . -name "STATUS.txt" -exec grep -lF "OPEN" \{} +

如果你想将它包装在一个脚本中,一个好的起点可能是:

#!/bin/sh

[ $# -ne 1 ] && echo "One argument required" >&2 && exit 2
find . -name "STATUS.txt" -exec grep -lF "$1" \{} +

正如@BroSlow所指出的,如果您正在寻找包含匹配的STATUS.txt文件的目录,这可能更符合您的要求:

fgrep --include='STATUS.txt' -rl 'OPEN' | xargs -L 1 dirname 

或更好

fgrep --include='STATUS.txt' -rl 'OPEN' |
           sed -e 's|^[^/]*$|./&|' -e 's|/[^/]*$||'
#              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#            simulate `xargs -L 1 dirname` using `sed`  
#      (no trailing `\`; returns `.` for path without dir part)                   

答案 2 :(得分:1)

尝试这样的事情

find -type f -name "STATUS.txt" -exec grep -q "OPEN" {} \; -exec dirname {} \;

或在脚本中

#!/bin/bash 
(($#==1)) || { echo "Usage: $0 <pattern>" && exit 1; }
find -type f -name "STATUS.txt" -exec grep -q "$1" {} \; -exec dirname {} \;

答案 3 :(得分:0)

您可以使用grepawk代替find:

grep -r OPEN * | awk '{split($1, path, ":"); print path[1]}' | xargs -I{} dirname {}

以上grep将列出包含&#34; OPEN&#34;的所有文件。在你的dir结构内递归。结果将是:

dir_1/subdir_1/STATUS.txt:OPEN
dir_2/subdir_2/STATUS.txt:OPEN
dir_2/subdir_3/STATUS.txt:OPEN

然后awk脚本将此输出拆分为冒号并打印它的第一部分(dir路径)。

dir_1/subdir_1/STATUS.txt
dir_2/subdir_2/STATUS.txt
dir_2/subdir_3/STATUS.txt

dirname将只返回目录路径,而不是文件名,我想它就是你想要的。

如果你想进一步发展,我会考虑使用Perl或Python,因为如果你想添加优先级和排序,它可能会变得更加混乱。

答案 4 :(得分:-1)

恕我直言,你应该写一个Python脚本:

  • 检查目录结构并找到名为STATUS.txt的所有文件。
  • 对于每个找到的文件:
    • 读取文件并执行mycommand,具体取决于文件包含的内容。

如果您希望稍后通过排序扩展脚本,您可以先找到所有有趣的文件,将它们保存到列表中,对列表进行排序并在排序列表上执行命令。

提示:http://pythonadventures.wordpress.com/2011/03/26/traversing-a-directory-recursively/