列出包含string1的所有唯一目录,其中包含包含string2

时间:2018-04-26 11:09:41

标签: bash shell find

假设我想查找包含某个字符串的所有目录(例如此处为a),其中还包含包含某个其他字符串的文件(例如.txt个文件)。这样做有什么不同的方法?一种方法是执行命令替换,例如:

mkdir dira; mkdir dirb
touch dira/file1.txt; touch dira/file2.doc; touch dirb/file3.doc
find `find . -type d -iname '*a'` -type f -iname '*.doc'

但是,如果我试图找到包含此文件的隐藏目录,则不起作用:

find `find . -type d -iname '.*'` -type f -iname '*.doc'

在这种情况下,它只是打印到stdout内部查找。怎么做到这一点?这样做的方法越多,就越具有指导性。 shell脚本也很有启发性。

2 个答案:

答案 0 :(得分:0)

这对我有用:

#!/bin/bash

# Setup test directories
mkdir dira dirb .dirc .dird .hiddena

# Setup test files
touch dira/filea1.doc dira/filea2.doc dira/filea3.txt
touch dirb/fileb1.doc dirb/fileb2.doc dirb/fileb3.txt
touch .dirc/filec1.doc .dirc/filec2.doc .dirc/filec3.txt
touch .dird/filed1.doc .dird/filed2.doc .dird/filed3.txt
touch .hiddena/filehiddena1.doc .hiddena/filehiddena2.doc .hiddena/filehiddena3.txt

find . -type d -name "*a" -print | while read DIR 
do
    find $DIR -type f -name "*a*.doc" -print
done

输出:

$ ./t.bash 
./dira/filea1.doc
./dira/filea2.doc
./.hiddena/filehiddena2.doc
./.hiddena/filehiddena1.doc

我的第一个版本使用了for循环,但是如果目录名中有空格,那么可能会导致问题,因此while read循环。

根据你的评论,我这样做了:

# Setup test directories
mkdir dira dirb .dirc .dird .hiddena

# Setup test files
touch dira/filea1.doc dira/filea2.doc dira/filea3.txt
touch dirb/fileb1.doc dirb/fileb2.doc dirb/fileb3.txt
touch .dirc/filec1.doc .dirc/filec2.doc .dirc/filec3.txt
touch .dird/filed1.doc .dird/filed2.doc .dird/filed3.txt
touch .hiddena/filehiddena1.doc .hiddena/filehiddena2.doc .hiddena/filehiddena3.txt
touch .hiddena/z

find . -type d -name "*a" -print | while read DIR 
do
    #find $DIR -type f -name "*a*.doc" -print
    find $DIR -type f -name z -print
done

我得到的输出是:

$ ./t.bash 
./.hiddena/z

所以我不明白为什么你会得到双z。

答案 1 :(得分:0)

要阻止评估实际目录(如./或../pwd/),只需使用:

find .* -mindepth 1 -maxdepth 1 -type f -iname '*.doc'
.dira/file11.doc
.dira/file10.doc
.dira/file9.doc
.dirb/file11.doc
.dirb/file10.doc
.dirb/file9.doc

使用后

touch .dir{a..b}/file{9..11}.doc

使用更长的模式.dir *更容易:

find .dir* -type f -iname '*.doc'
.dira/file11.doc
.dira/file10.doc
.dira/file9.doc
.dirb/file11.doc
.dirb/file10.doc
.dirb/file9.doc

命令替换也有效(请不要使用过时的反引号)

find $(find . -mindepth 1 -type d -iname ".*") -type f -iname '*.doc'
./.dirb/file11.doc
./.dirb/file10.doc
./.dirb/file9.doc
./.dira/file11.doc
./.dira/file10.doc
./.dira/file9.doc