我有以下文件:
100005.txt 107984.txt 116095.txt 124152.txt 133339.txt 139345.txt 18147.txt 25750.txt 32647.txt 40390.txt 48979.txt 56502.txt 64234.txt 72964.txt 80311.txt 888.txt 95969.txt
100176.txt 108084.txt 116194.txt 124321.txt 133435.txt 139438.txt 18331.txt 25940.txt 32726.txt 40489.txt 49080.txt 56506.txt 64323.txt 73063.txt 80481.txt 88958.txt 9601.txt
100347.txt 108255.txt 116378.txt 124494.txt 133531.txt 139976.txt 18420.txt 26034.txt 32814.txt 40589.txt 49082.txt 56596.txt 64414.txt 73163.txt 80580.txt 89128.txt 96058.txt
100447.txt 108343.txt 116467.txt 124594.txt 133627.txt 140519.txt 18509.txt 26128.txt 32903.txt 40854.txt 49254.txt 56768.txt 64418.txt 73498.txt 80616.txt 89228.txt 96148.txt
100617.txt 108432.txt 11647.txt 124766.txt 133728.txt 14053.txt 1866.txt 26227.txt 32993.txt 41026.txt 49308.txt 56857.txt 6449.txt 73670.txt 80704.txt 89400.txt 96239.txt
10071.txt 108521.txt 116556.txt 124854.txt 133830.txt 141062.txt 18770.txt 26327.txt 33093.txt 41197.txt 49387.txt 57029.txt 64508.txt 7377.txt 80791.txt 89500.txt 96335.txt
100788.txt 10897.txt 116746.txt 124943.txt 133866.txt 141630.txt 18960.txt 2646.txt 33194.txt 41296.txt 4971.txt 57128.txt 64680.txt 73841.txt 80880.txt 89504.txt 96436.txt
部分文件如下:
spec:
annotations:
name: "ubuntu4"
labels:
key: "cont_name"
value: "ubuntuContainer4"
labels:
key: "cont_service"
value: "UbuntuService4"
task:
container:
image: "ubuntu:latest"
args: "tail"
args: "-f"
args: "/dev/null"
mounts:
source: "/home/testVolume"
target: "/opt"
replicated:
replicas: 1
我想获取包含 ubuntu AND 副本的每个文件名。
我试过awk '/ubuntu/ && /replicas/{print FILENAME}' *.txt
,但它似乎对我不起作用。
有关如何解决此问题的任何想法?
答案 0 :(得分:4)
Grep可以返回与字符串匹配的文件列表。您可以嵌套该grep调用,以便首先获得与 ubuntu 匹配的文件列表,然后使用该文件列表获取与副本匹配的文件列表。 / p>
grep -l replicas $( grep -l ubuntu *.txt )
这假设至少有一个文件与ubuntu匹配。要绕过该限制,您可以先为一个文件的存在添加测试,然后进行组合搜索:
grep -q ubuntu *.txt && grep -l replicas $( grep -l ubuntu *.txt )
答案 1 :(得分:2)
通过对每个字符串使用计数器检查两个字符串是否出现在给定文件中,然后检查它们是否递增。您可以使用GNU awk上提供的BEGINFILE
执行此操作:
awk 'BEGINFILE {ub=0; re=0}
/ubuntu/ {ub++}
/replicas/ {re++}
(ub>0 && re>0) {print FILENAME; nextfile}' *.txt
当它开始读取文件时,它将两个计数器设置为0:一个用于一个字符串,另一个用于另一个字符串。当找到其中一个模式时,它会增加其相应的计数器。然后它继续检查两个计数器是否已增加。如果是这样,它将使用包含该字符串的FILENAME
变量打印其文件名。此外,它使用nextfile
跳过文件的其余部分,因为无需继续检查模式。
答案 2 :(得分:2)
awk '/ubuntu/ && /replicas/{print FILENAME}' *.txt
在同一行查找两个正则表达式。要在同一个文件中找到它们,但可能在与GNU awk for ENDFILE的单独行中找到它们:
awk '/ubuntu/{u=1} /replicas/{r=1} ENDFILE{if (u && r) print FILENAME; u=r=0}' *.txt
或更有效地添加gawks nextfile构造并优先切换到BEGINFILE(如@fedorqui已经显示)而不是ENDFILE,因为文件读取之间的所有内容都是设置2个变量:
awk 'BEGINFILE{u=r=0} /ubuntu/{u=1} /replicas/{r=1} u && r{print FILENAME; nextfile}' *.txt
其他问题就是:
awk '
FNR==1{prt()} /ubuntu/{u=1} /replicas/{r=1} END{prt()}
function prt() {if (u && r) print fname; fname=FILENAME; u=r=0}
' *.txt
答案 3 :(得分:1)
如果没有访问过子目录:
for f in *.txt
do
grep -q -m1 'ubuntu' $f && grep -q -m1 'replicas' $f && echo "found: $f"
done
或作为oneliner:
for f in *.txt ; do grep -q -m1 'ubuntu' $f && grep -q -m1 replicas $f && echo found:$f ; done
-q使得grep安静,因此匹配不显示,-m1只搜索1个匹配,因此grep可以快速报告匹配。
&&是短路的,所以如果第一个grep找不到任何东西,那么第二个就不会尝试。
对于在管道中进一步处理文件,你当然会消除发现的"发现:"。