如何从文本文件中打印重复值的全名?
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, @files
:grep
选择 @files
数组的元素,其中后缀是一个 dupe。
Perl 单行代码使用这些命令行标志:
-e
: 告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行内联代码之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
我有一个类似下面的文件。
$ 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, @files
:grep
选择 @files
数组的元素,其中后缀是一个 dupe。
Perl 单行代码使用这些命令行标志:
-e
: 告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行内联代码之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches