1

Я пытаюсь создать пакет, PowerShell или что-нибудь, что новичок, как я, мог бы легко выполнить для выполнения следующей задачи. Любая помощь будет принята с благодарностью.

У меня есть несколько тысяч PDF-файлов в папке, которые я пытаюсь отсортировать. Проблема в том, что папка включает в себя старые и новые версии тех же документов PDF. Я только хочу сохранить самую новую версию каждого уникального документа. Пересмотренная версия обозначена добавлением буквы в конце имени файла (AZ). Вот примерный список.

670BA-11-001.pdf
670BA-11-001A.pdf
670BA-11-001B.pdf
670BA-12-001.pdf
670BA-15-030C.pdf
670BA-49-120AC.pdf
670BA-49-120AD.pdf
  • Все файлы начинаются с " 670BA "
  • Следующие числа меняются. 670BA-XX-XXX.pdf
  • Файл без буквы в конце имени файла указывает, что это оригинальная ревизия.
  • Файл с буквой в конце имени файла указывает, что это пересмотренная версия.
  • Пересмотры идут от A-Z а затем AA-AZ... и так далее, и тому подобное.

В идеале я хотел бы, чтобы командный файл удалил более старые версии и оставил самую новую версию каждого уникального документа. В этом случае вывод должен выглядеть следующим образом:

670B-11-001B.pdf
670B-12-001.pdf
670B-15-030C.pdf
670BA-49-120AD.pdf

Мне был предоставлен следующий код, однако я считаю, что он в Unix (опять же простите мое отсутствие знаний здесь). Будет ли это работать, если бы я мог преобразовать его в команду Windows?

codes=`ls | sort | cut -d'-' -f2 | uniq`
for f in $codes; do old=`ls *-$f-* | head -n -1`; rm -vf $old; done

Вот что происходит;

ls | sort lists all the files in lexical order
cut -d'-' -f2 | uniq 

разбивает имена файлов на «-», берет двухзначное число из середины и избавляется от дубликатов.

ls *-$f-* | head -n -1 

перечисляет все файлы для двузначного кода, кроме последнего - который является самым новым.

rm -f $old 

удаляет эти старые файлы, и -f предотвращает его сбой, поскольку список пуст.

SAMPLE RUN;

/tmp# touch 601R-11-001.pdf   601R-11-001B.pdf  601R-15-030C.pdf  601R-25-005E.pdf   601R-49-120AD.pdf  601R-11-001A.pdf  601R-12-001.pdf   601R-25-005D.pdf  601R-49-120AC.pdf

/tmp# codes=`ls | sort | cut -d'-' -f2 | uniq`

/tmp# echo $codes
11 12 15 25 49

/tmp# for f in $codes; do old=`ls *-$f-* | head -n -1`; rm -vf $old; done

removed '601R-11-001.pdf'
removed '601R-11-001A.pdf'
removed '601R-25-005D.pdf'
removed '601R-49-120AC.pdf'

1 ответ1

1

Если у вас есть работающий код Bash (я не проверял скрипт в вашем посте), вы можете запустить его в Windows, установив Ubuntu в подсистему Windows для Linux. После того, как вы настроили Ubuntu, вы можете открыть приглашение Bash, используя пункт Bash on Ubuntu для Windows в меню «Пуск» (если есть), или введя bash в поле «Выполнить». Структура Windows C:\ находится в /mnt/c/ в среде Bash.

Кроме того, вы можете использовать PowerShell!

$revPos = '670BA-XX-XXX'.Length
dir '670BA*.pdf' | group @{e={ $_.Name.Substring(0, $revPos) }} | % {
    $revs = $_.Group | % { $_.Name.Substring($revPos).Split('.')[0] } | group Length | sort -Descending -Property @{e={ [int]$_.Name }} | % { $_.Group | sort -Descending }
    $fileSet = $_.Name
    $revs | % { $fileSet + $_ + '.pdf' } | select -Skip 1 | del
}

Давайте разберем его по компонентам линии и конвейера:

  1. Для удобства сохраните длину части, которая идентифицирует документ, т.е. индекс ревизии. Это предполагает, что идентификаторы документа всегда имеют одинаковый размер.
  2. Получить все наборы файлов.
    • Получить все файлы в текущем каталоге, которые начинаются с 670BA и являются .pdf s.
    • Сгруппируйте их по первой части имени, идентификатору документа. Бизнес с @{e={ является пользовательским свойством.
    • Перебирать группы.
  3. Получить отсортированный список идентификаторов ревизий для текущей группы.
    • Свойство Group находится в выходных объектах команды group.
    • Для каждого файлового объекта, включенного в группу, выберите часть его имени после идентификатора документа, но перед точкой в .pdf . Это идентификатор ревизии. Если файл не исправлен, это будет строка нулевой длины.
    • Сгруппируйте идентификаторы ревизий по длине.
    • Сортируйте объекты группы (не элементы в них) по длине строк их членов. Свойство Name группы содержит значение свойства, которое использовалось для группировки объектов.
    • Для каждого из этих групповых объектов сортируйте их членов по алфавиту. Это объединит все группы вместе в переменную $revs , отсортированную в соответствии с вашей системой управления версиями.
  4. Храните значение Name файловой группы в другой переменной , чтобы держать его доступным, так как для другой-eaches % будет затенять переменной $_
  5. Удалите все кроме последней редакции в группе документов.
    • Используйте записи в списке $revs .
    • Перепишите полное имя файла для каждого идентификатора ревизии. $_ теперь содержит идентификаторы ревизий из $revs .
    • Пропустите первую запись, так как она самая новая, та, которую мы хотим сохранить.
    • Удалите файлы, соответствующие всем записям, оставшимся в конвейере. Если вы хотите протестировать скрипт, не удаляя ничего , добавьте пробел и ключ -WhatIf в конце этой строки. В режиме «что если» del просто распечатает то, что сделал бы.
  6. Завершите итерацию группы документов.

Чтобы использовать скрипт, сохраните его как файл .ps1 , например, revnewest.ps1 . Если вы этого еще не сделали, следуйте инструкциям в разделе «Включение сценариев» вики-тега PowerShell . Затем вы можете поместить его в папку с документами, открыть там PowerShell и запустить его так:

.\revnewest.ps1

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .