如何使用 Perl 根据差异结果将目录中的文件排序到不同的文件夹中



我在一个目录中有一组具有唯一名称的txt文件,每个文件都有一个唯一的名称,但它们的许多内容完全相同。我需要一种好方法将这些txt文件排序到单独的文件夹中,以便每个特定文件夹中的所有文件都包含相同的内容。这些文件需要全局差异以确保相似性。

例如,如果 6 个文件具有以下属性(= 表示差异结果相同(

a.txt = b.txt = c.txt
d.txt = e.txt != a.txt
f.txt != (a.txt nor d.txt)

然后,我需要将这些文件移动到如下所示的目录:

/folder1/ contains (a.txt, b.txt, c.txt)
/folder2/ contains (d.txt, e.txt)
/folder3/ contains (only f.txt)

谢谢!

我通常不会不费吹灰之力地回答问题,但我们对脚本比对程序更宽容一些,我很无聊,想刷新一下我的尴尬技能。

以下是使用 awk 和 Perl 命令行脚本的两种不同方法。这些应在一行中输入。 两者都使用一小组文件进行了测试。

注意:这些脚本不执行实际操作。它旨在将输出重定向到文件中,然后在仔细验证它是否按预期执行后,将该文件作为脚本执行以执行移动。

Perl:

for i in *.txt; do echo `sha1sum $i`; done | sort | perl -ne 
'BEGIN {$a=1} 
($h,$f)=split; 
if ($h ne $c) { $c=$h; $d="folder".$a++; print "mkdir $dn"} 
print "mv $f $dn"'

哎呀:

for i in *.txt; do echo `sha1sum $i`; done | sort | awk 
'BEGIN {a=1} 
$1!=c { c=$1; d="folder" a++; print "mkdir ",d} 
{print "mv ",$2," ", d}'

它们都使用相同的初始管道:对当前目录中的每个文件运行sha1sum,按哈希值排序,然后调用Perl或awk。 应单独运行管道(省略最后一个|和整个awkperl命令(以查看原始输出的外观。

脚本查找哈希值的更改,并在每次更改时创建一个新文件夹,然后将文件和具有匹配哈希的后续文件移动到新文件夹。

给定一组 7 个输入文件,每个输入文件由一个字节组成:

Filename   Contents
--------   --------
a.txt      1
b.txt      2
c.txt      1
d.txt      1
e.txt      5
f.txt      1
g.txt      5

原始管道输出为:

$ for i in *.txt; do echo `sha1sum $i`; done | sort
5d9474c0309b7ca09a182d888f73b37a8fe1362c e.txt
5d9474c0309b7ca09a182d888f73b37a8fe1362c g.txt
7448d8798a4380162d4b56f9b452e2f6f9e24e7a b.txt
e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e a.txt
e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e c.txt
e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e d.txt
e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e f.txt

最终输出为

mkdir  folder1
mv  e.txt   folder1
mv  g.txt   folder1
mkdir  folder2
mv  b.txt   folder2
mkdir  folder3
mv  a.txt   folder3
mv  c.txt   folder3
mv  d.txt   folder3
mv  f.txt   folder3

顺便说一句,这说明了在编写执行批量操作的脚本时应遵循的明智规则。 永远不要让脚本一开始就执行操作,让脚本编写包含要执行的批量操作的脚本。 仅当您确信它已经过全面测试和调试时,才升级到执行实际操作。

最新更新