这是我拥有的文件名;
cpu-system-2016-05-06
cpu-system-2017-05-08
cpu-wait-2017-05-08
cpu-wait-2016-05-06
cpu-wait-2017-05-07
cpu-interrupt-2017-05-08
cpu-interrupt-2016-05-07
cpu-softirq-2017-05-07
cpu-softirq-2017-05-08
cpu-softirq-2017-05-06
我想通过解析名称-201
并考虑第一部分以便接收这样的输出;
cpu-system
cpu-wait
cpu-interrupt
cpu-softirq
最佳解决方案是什么?
答案1
我不会说这是“最佳解决方案”,但考虑到
$ ls cpu*
cpu-interrupt-2016-05-07 cpu-softirq-2017-05-06 cpu-softirq-2017-05-08 cpu-system-2017-05-08 cpu-wait-2017-05-07
cpu-interrupt-2017-05-08 cpu-softirq-2017-05-07 cpu-system-2016-05-06 cpu-wait-2016-05-06 cpu-wait-2017-05-08
然后
$ ls cpu* | cut -d- -f1,2 | uniq
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
答案2
考虑任何可能的文件名,从该目录:
printf '%s\0' cpu-*-201* | \
awk -F'-' 'BEGIN{RS="\0"} $3~/^201/ {a[$1"-"$2]} END{for(i in a) print i}'
printf '%s\0' cpu-*-201*
打印以 NUL 分隔的文件名awk
将记录分隔符设置为 NUL,并将-
分隔的前两个字段(中间用-
)作为关联数组的键a
(如果第三个字段以 开头)201
。最后,我们只需使用 打印数组键即可{a[$1"-"$2]} END{for(i in a) print i}
sort
如果需要,您可以在打印前两个字段(用 分隔)后摆脱数组和杠杆-
:
printf '%s\0' cpu-*-201* | \
awk -F'-' 'BEGIN{RS="\0"} $3~/^201/ {print $1"-"$2}' | sort -u
假设没有不寻常的文件名,则有很多选项,所有选项都借助于以下方法sort -u
来获得唯一性:
grep
,使用 PCRE:printf '%s\n' cpu-*-201* | grep -Po '^.*(?=-201)' | sort -u
sed
:printf '%s\n' cpu-*-201* | sed -E 's/^(.*)-201.*/\1/' | sort -u
awk
:printf '%s\n' cpu-*-201* | awk -F'-' '$3~/^201/ {a[$1"-"$2]} END{for(i in a) print i}' printf '%s\n' cpu-*-201* | awk -F'-' '$3~/^201/ {print $1"-"$2}' | sort -u
cut
,假设稳定的字段,这是盲目地获得前两个字段:printf '%s\n' cpu-*-201* | cut -d- -f1,2 | sort -u
例子:
% printf '%s\n' cpu-*-201*
cpu-interrupt-2016-05-07
cpu-interrupt-2017-05-08
cpu-softirq-2017-05-06
cpu-softirq-2017-05-07
cpu-softirq-2017-05-08
cpu-system-2016-05-06
cpu-system-2017-05-08
cpu-wait-2016-05-06
cpu-wait-2017-05-07
cpu-wait-2017-05-08
% printf '%s\0' cpu-*-201* | awk -F'-' 'BEGIN{RS="\0"} $3~/^201/ {a[$1"-"$2]} END{for(i in a) print i}'
cpu-softirq
cpu-interrupt
cpu-wait
cpu-system
% printf '%s\0' cpu-*-201* | awk -F'-' 'BEGIN{RS="\0"} $3~/^201/ {print $1"-"$2}' | sort -u
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
% printf '%s\n' cpu-*-201* | grep -Po '^.*(?=-201)' | sort -u
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
% printf '%s\n' cpu-*-201* | sed -E 's/^(.*)-201.*/\1/' | sort -u
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
% printf '%s\n' cpu-*-201* | awk -F'-' '$3~/^201/ {a[$1"-"$2]} END{for(i in a) print i}'
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
% printf '%s\n' cpu-*-201* | awk -F'-' '$3~/^201/ {print $1"-"$2}' | sort -u
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
% printf '%s\n' cpu-*-201* | cut -d- -f1,2 | sort -u
cpu-interrupt
cpu-softirq
cpu-system
cpu-wait
答案3
Perl 解决方案
我们可以使用 Perl 提取-201
子字符串之前的所需部分,并将项目存储到哈希中,其中每个提取的字符串将是一个键值。
$ perl -ne '($var=$_)=~s/^(.*)-201(.*)/\1/g;$hash{$var}+=1; END{ do{print }for keys %hash}' input.txt
cpu-system
cpu-softirq
cpu-wait
cpu-interrupt
一旦处理完成,结果将只留下唯一值作为键,但请注意,它们不会按照特定的排序顺序排列(因此如果您想要排序输出,请将输出通过管道传输到sort
命令)