如何去除文件名中不常见的部分,保留独特的部分

如何去除文件名中不常见的部分,保留独特的部分

这是我拥有的文件名;

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命令)

相关内容