1

В настоящее время пытаются выяснить способ переименования файлов PDF в определенной папке (/root), которые прямо или косвенно находятся в папке purchases которая сама прямо или косвенно находится в папке /root . Я хотел бы добиться этого с помощью PowerShell, но не могу достичь чего-то большего, чем примеры, которые я нашел по многочисленным темам.

Например, с этой структурой каталогов:

/root/<subfolder1>/purchases/invoice1.pdf
/root/<subfolder1>/order.pdf
/root/<subfolder2>/purchases/invoice2.pdf

Предполагается переименовывать или удалять только те файлы PDF, которые находятся в папках "покупок". Файлы PDF в любой другой папке нельзя трогать.

Имена <subfolderX> неизвестны (то есть они могут быть чем угодно, например, "a" или "b").

Скрипт должен рекурсивно запускать все папки.

Любое руководство по достижению этого будет оценено.

3 ответа3

2

Короткий ответ

Чтобы вывести на экран имена файлов PDF, которые прямо или косвенно содержатся в прямом или косвенном подкаталоге d:\root именных purchases , вы можете использовать:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName

Краткое объяснение: команда рекурсивно находит все прямые и непрямые подкаталоги d:\root именованных purchases , затем рекурсивно находит все файлы PDF в каждом из этих подкаталогов, а затем возвращает полный путь к каждому из этих файлов PDF.

Другие варианты использования

Чтобы удалить эти файлы PDF:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | ri

Чтобы переименовать эти PDF-файлы (например, добавив префикс и суффикс к базовому имени):

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % { rni $_ "pref-$($_.BaseName)-suff.pdf" }

Чтобы удалить каталоги purchases вместе со всем их содержимым:

gci -Directory -Recurse d:\root\purchases | ri -Recurse

Детальное объяснение

  • gci - это псевдоним Get-ChildItem.
  • gci -Directory -Recurse d:\root\purchases возвращает все каталоги (-Directory), чьи имена являются purchases которые являются прямыми или косвенными (-Recurse) вложенными папками в d:\root\ . Другими словами, он будет возвращать d:\root\purchases (если он существует), а также d:\root\b\c\purchases и d:\root\a\purchases . Это не очень интуитивно понятно и, по-видимому, не объясняется в документации, но это текущее поведение (в PowerShell 6).
  • % является псевдонимом ForEach-Object. Он выполняет блок скрипта (заключенный в фигурные скобки ({}) для каждого объекта в конвейере.
  • gci -Recurse "$_\*.pdf" извлекает список файлов PDF, которые (прямо или косвенно) содержатся в ранее найденных каталогах purchases .
  • % FullName просто используется для отображения пути к этим файлам PDF.
  • ri является псевдонимом для Remove-Item. Он удаляет ранее вычисленный список файлов PDF (поскольку параметр -Path команды Remove-Item принимает входные данные конвейера).
  • ri -Recurse позволяет удалить ранее рассчитанный список каталогов purchases вместе с их содержимым.
  • rni $_ "pref-$($_.BaseName)-suff.pdf" добавляет префикс (pref-) и суффикс (-suff) к базовому имени $_.BaseName текущего файла в конвейере (т.е. каждый из файлов PDF, которые мы ищем). Базовое имя файла - это имя файла без его расширения, а rni - псевдоним для Rename-Item.

Тестирование этого решения (онлайн или локально)

Самое простое - попробовать это решение онлайн.

В противном случае вы можете создать образец структуры каталогов в test папке текущего рабочего каталога со следующим фрагментом (будьте осторожны: измените .\test на что-то другое, если у вас уже есть test папка в текущем каталоге):

mkdir -ErrorAction SilentlyContinue .\test\a\purchases, .\test\a\e\, .\test\b\c\purchases\
Out-File .\test\a\purchases\invoice1.pdf
Out-File .\test\a\order1.pdf
Out-File .\test\a\e\order2.pdf
Out-File .\test\b\c\purchases\invoice2.pdf
Out-File .\test\b\c\purchases\invoice3.pdf

Чтобы просмотреть все файлы в этой структуре каталогов, вы можете использовать:

gci -Recurse -File .\test | % FullName

Что бы вернуть что-то вроде:

D:\test\a\order1.pdf
D:\test\a\e\order2.pdf
D:\test\a\purchases\prefix-invoice1-suffix.pdf
D:\test\b\c\purchases\prefix-invoice2-suffix.pdf
D:\test\b\c\purchases\prefix-invoice3-suffix.pdf

(Где D: заменяется вашим текущим рабочим каталогом.)

Выполнение команды, предоставленной в качестве ответа (gci -Directory -Recurse .\test\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName), отобразит файлы, которые необходимо удалить или удалить:

D:\test\a\purchases\invoice1.pdf
D:\test\b\c\purchases\invoice2.pdf
D:\test\b\c\purchases\invoice3.pdf

Чтобы очистить после вашего теста:

rm -Recurse .\test
1

Юсеф Абиди дал вам ответ, нацеленный на один диск, но кажется, что вы говорите, путь к папке.\ Покупки, неизвестно?

Тем не менее, правило форума состоит в том, что вы должны предоставить то, что вы пробовали, и ошибки, с которыми вы столкнулись, чтобы показать, какова ваша конечная цель, а не заставлять нас догадываться, и, как многие скажут, «делайте свою работу за вас». Люди здесь очень полезны, но, ну, вы знаете.

Все это, как говорится, если мое предположение верно. По сути, сделайте фильтр для папки покупок на любом диске на хосте, а затем откройте PDF-файл в этой папке и сделайте, как хотите.

Это на самом деле просто однострочная конвейерная команда - если вышеприведенное является верным предположением

(Get-PSDrive).Root -like '*:\' | 
% { (Get-ChildItem -Path ((Get-ChildItem -Path $_ -recurse -Filter Purchases -Directory -ErrorAction SilentlyContinue).FullName) -Filter '*.pdf' -Verbose).FullName }

# Results

C:\purchases\powershell-cheat-sheet.pdf
C:\purchases\PSPunctuationWallChart_1_0_4.pdf
D:\Temp\purchases\powershell-cheat-sheet.pdf
D:\Temp\purchases\PSPunctuationWallChart_1_0_4.pdf

Конечно, вы можете разбить эту строку на что-то другое.

0

Я согласен, что делать домашнее задание очень важно для сообщества. Я понял это с помощью gci и filter, но не смог импровизировать часть двойного gci между кавычками.

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

Итак, еще раз большое спасибо!

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