如何从文本文件中打印重复值的全名?

How to print full name of the duplicate values from a text file?

我有一个类似下面的文件。

$ ls -1 *.ts | sort -V

media_w1805555829_b1344100_sleng_2197.ts
media_w1805555829_b1344100_sleng_2198.ts
media_w1805555829_b1344100_sleng_2199.ts
media_w1805555829_b1344100_sleng_2200.ts
media_w1501256294_b1344100_sleng_2199.ts
media_w1501256294_b1344100_sleng_2200.ts
media_w1501256294_b1344100_sleng_2201.ts
media_w1501256294_b1344100_sleng_2202.ts

这将打印重复行:

$ ls -1 *.ts | sort -V | grep -oP '.*_\K.*(?=.ts)' | sort | uniq -d | sed 's/^/DUPLICATE---:> /'

DUPLICATE---:> 2199
DUPLICATE---:> 2200

我想要输出:

DUPLICATE---:> media_w1805555829_b1344100_sleng_2199.ts
DUPLICATE---:> media_w1805555829_b1344100_sleng_2200.ts
DUPLICATE---:> media_w1501256294_b1344100_sleng_2199.ts
DUPLICATE---:> media_w1501256294_b1344100_sleng_2200.ts
ls -1 *.ts | sort -V | awk -F[_.] '
           { 
               map[]+=1;
               map1[][[=10=]] 
           } 
       END { 
               for (i in map) 
                             { 
                               if(map[i]>1) 
                                          { 
                                            for (j in map1[i]) 
                                                               { 
                                                                 print "DUPLICATE---:> "j 
                                                               } 
                                           } 
                             } 
            }' | sort

一个班轮

ls -1 *.ts | sort -V | awk -F[_.] '{ map[]+=1;map1[][[=11=]] } END { for (i in map) { if(map[i]>1) { for (j in map1[i]) { print "DUPLICATE---:> "j } } } }' | sort

使用 awk,将字段分隔符设置为 _ 或 。然后创建两个数组。第一个(映射)保存文件路径中每个数字的计数。第二个 (map1) 是一个多维数组,第一个索引是数字,第二个是完整的行(文件路径)。然后我们在末尾遍历数组映射并检查是否有任何大于 1 的计数。如果找到任何内容,我们将遍历第二个 map1 数组并打印行(第二个索引)以及其他文本。我们终于运行再次通过排序得到了需要的顺序,。

使用这个 Perl 单行代码:

ls -1 *.ts | perl -lne '
$cnt{}++ if /_(\d+).ts$/; 
push @files, [ $_,  ]; 
END { 
    for ( grep $cnt{$_->[1]} > 1, @files ) { 
        print "DUPLICATE---:> $_->[0]" 
    } 
}'

这消除了排序的需要。
%cnt 散列包含后缀的计数(您要在其中查找重复项的文件名部分)。 @files 是数组的数组。它的每个元素都是一个匿名数组,包含 2 个元素:文件名和后缀。
grep $cnt{$_->[1]} > 1, @filesgrep 选择 @files 数组的元素,其中后缀是一个 dupe。

Perl 单行代码使用这些命令行标志:
-e : 告诉 Perl 查找内联代码,而不是在文件中。
-n :一次循环输入一行,默认分配给 $_
-l : 在执行内联代码之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"),并在打印时附加它。

另请参见:
perldoc perlrun: how to execute the Perl interpreter: command line switches