Как отсортировать файлы в каталоге по разным папкам на основе их различий с помощью Perl - PullRequest
0 голосов
/ 12 июня 2018

У меня есть группа текстовых файлов с уникальными именами в каталоге, каждый из которых имеет уникальное имя, но многие из их содержимого абсолютно одинаковы.Мне нужен хороший способ сортировки этих текстовых файлов по отдельным папкам, чтобы все файлы в каждой конкретной папке содержали идентичное содержимое.Файлам нужен глобальный diff для обеспечения сходства.

например, если 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)

Большое спасибо!

1 Ответ

0 голосов
/ 12 июня 2018

Обычно я не отвечаю на вопрос без каких-либо усилий, но мы, как правило, немного более снисходительны в отношении сценариев, чем программ, и мне было скучно, и я хотел немного обновить свои навыки в awk.

Вот два разных способа использования сценариев командной строки 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 $d\n"} 
     print "mv $f $d\n"'

Awk:

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.Вы должны запустить конвейер отдельно (пропустите последнюю команду | и всю команду awk или perl), чтобы увидеть, как выглядит необработанный вывод.

Сценарии ищут изменение значения хеш-функции и создают новую папку каждый раз, когда она изменяется, затем перемещают файл и последующие файлы с совпадающими хэшами в новую папку.

При наличии набора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

BTW,это иллюстрирует правило, которому вы должны следовать при написании скриптов, которые выполняют массовые операции.Никогда не позволяйте сценарию выполнять начальную операцию, пусть сценарий напишет сценарий , содержащий объемные операции, которые вы хотите выполнить.Обновитесь до выполнения реальных операций только тогда, когда вы положительный , он полностью протестирован и отлажен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...