我将向您显示此命令的输出:
[root@test ~]# df -P -k -t xfs | egrep '*/PATH whichI don't have/*'
运行命令时,输出如下:
[root@test ~]# df -P -k -t xfs | egrep '*/PATH whichI don't have/*'
10.20.30.40:/var/contain/name1 3877121024 215982080 3661138944 6% /fofo
10.20.30.50:/var/beta/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.40:/var/contain/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.50:/var/beta/toto 3877121024 215982080 3661138944 6% /fofo
10.20.30.60:/var/alpha/name2 3877121024 215982080 3661138944 6% /fofo
如果仅一次找到相同的路径,我只想从其他不同的行中提取一行。所以我只想从每多行中提取一行。预期输出:
[root@test ~]# df -P -k -t xfs | egrep '*/PATH whichI don't have/*'
10.20.30.40:/var/contain/name1 3877121024 215982080 3661138944 6% /fofo
10.20.30.50:/var/beta/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.60:/var/alpha/name2 3877121024 215982080 3661138944 6% /fofo
如果我找到相同的路径,则只想从每多行中提取一行。 IP地址不相同,如果多行包含相同的地址,我希望仅保留一行。希望对您有帮助
谢谢。
答案 0 :(得分:1)
我认为grep
是此工作的错误工具,而Awk是更好的选择(也可以使用Perl或Python,并且无疑也可以使用其他脚本语言)。
您似乎想要每个IP地址的第一条记录,这是日志格式中直到第一个冒号为止的字段。这表明您需要:
awk -F: '!($1 in a) { print; a[$1] = 1 }'
鉴于问题中的输入显示,输出为:
10.20.30.40:/var/contain/name1 3877121024 215982080 3661138944 6% /fofo
10.20.30.50:/var/beta/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.60:/var/alpha/name2 3877121024 215982080 3661138944 6% /fofo
能否请您解释一下命令的作用?
Awk使用可以将字符串作为下标的关联数组。 -F:
选项意味着Awk将行分割为冒号处的字段,因此$1
是第一个冒号(IP地址)之前的文本,并且(在此示例中)$2
是所有第一个冒号之后的文本,而$0
是整个输入行。 Awk程序是“模式-动作”对(或“表达式”或“条件”加上“动作”对)的序列。如果明确指定了该操作,则将其括在括号中(如果未指定,则默认为print $0
-打印输入行)。如果未指定模式,则等同于匹配所有行。
在此程序中,条件为!($1 in a)
,它检查$1
是否作为下标出现在数组a
中;如果未显示下标,则整个表达式的计算结果为true。当条件为真时,将采取措施。进行打印(隐式$0
),并将a[$1]
设置为1
,以便如果再次出现相同的IP地址,则条件将评估为false,从而防止重复IP地址。 / p>
如果要使用最后一个条目而不是第一个条目,则可以使用变体方案,其中每行将保存在数组{ a[$1] = $0 }
的正确条目中,然后会有一个{{ 1}}模式在输入完成后运行:END
。主题有无尽的变化。
如果我想做同样的事情,但基于IP地址后面的单词而不是IP地址( / word / ),该怎么办?
很大程度上取决于您如何定义“单词”(或'/ word /')。为了使生活更轻松,我计划将一个单词视为一组连续的非空白字符。字段分隔符可以是正则表达式,因此我将使用END { for (i in a) print a[i] }
来分隔冒号或空格; IP地址后面的单词就是[: ]
。脚本几乎没有变化:
$2
由于冒号后面的名称在示例数据中都不同,因此所有5行都出现在输出中。但是,如果您多次在同一文件上运行脚本(在显示的脚本后添加awk -F '[: ]' '!($2 in a) { print; a[$2] = 1 }'
,其中文件data data
包含示例输入),则输出中只会得到一行的副本,这令人放心。
答案 1 :(得分:-1)
好吧,假设您只对/ x / y部分感兴趣,我想您可以这样做:
df -P -k -t xfs > tmpFile
cat tmpFile |cut -d: -f2|cut -d/ -f1-3|sort -u > tmpFile2
while read line; do grep $line tmpFile|head -1; done < tmpFile2
对于您上面提供的数据,输出为
10.20.30.40:/var/alpha/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.40:/var/beta/name2 3877121024 215982080 3661138944 6% /fofo
10.20.30.40:/var/contain/name1 3877121024 215982080 3661138944 6% /fofo
希望这会有所帮助。