2015-06-24 3 views
1

У кого-нибудь есть идеи о том, как переименовывать файлы, находя ассоциацию с индексным файлом?Переименование файлов с индексом (Excel)

У меня есть структура файлов/папок, как следующее: имя папки = «Doe, John EO11-123» несколько файлов в этой папке

индексный файл (MS Excel) имеет несколько колонок. Он содержит имена в 2 столбцах (первый и последний). Он также имеет столбец, содержащий номер EO11-123.

Что бы я хотел сделать, это написать сценарий, чтобы посмотреть имена папок в каталоге, сравнить/найти связанное значение в индексном файле (например, этот номер EO11-123), а затем переименовать все файлы в папка с использованием значения 4-го столбца в индексе.

Так,

Имя папки = "Doe, John EO11-123", индекс column1 содержит то же самое значение "EO11-123", используйте COLUMN2 значение "111111_000000" и переименовать все файлы в этой папке каталога для " 111111_000000_0 "," 111111_000000_1 "," 111111_000000_2 "и так далее.

Это возможно с помощью powershell или vbscript?

+0

Будут ли имена папок всегда в этом формате? 'LastName, FirstName ID #', если это так должно быть достаточно просто. Я лично использовал [этот скрипт] (https://gallery.technet.microsoft.com/office/17bcabe7-322a-43d3-9a27-f3f96618c74b) из галереи MS Script, чтобы импортировать данные в PowerShell, но для упрощения ссылок. – TheMadTechnician

+0

Да все имена папок находятся в этом формате. Есть ли причина импортировать файл в PowerShell? Преимущество? Как я могу использовать эти импортированные данные для переименования файлов? –

ответ

0

Хорошо, я отвечу на ваши вопросы в вашем комментарии. Импорт данных в PowerShell позволяет вам создать массив в PowerShell, который вы можете сопоставить, или еще лучше сделать HashTable ссылкой для ваших целей переименования. Я расскажу об этом позже, но это лучше, чем попросить PowerShell поговорить с Excel и использовать функции поиска Excel, так как все это в PowerShell, и нет зависимостей сторонних приложений. Что касается импорта, этот скрипт - это функция, которую вы можете загрузить в текущий сеанс, поэтому вы запускаете эту функцию, и она автоматически позаботится об импорте для вас (она открывает Excel, а затем открывает файл XLS (x), сохраняет его как временный CSV-файл, закрывает Excel, импортирует этот CSV-файл в PowerShell, а затем удаляет временный файл).

Теперь вы не заявить, что ваш файл XLS выглядит, так что я буду считать, что у него есть строка заголовка, и выглядит примерно так:

FirstName | Last Name | Identifier | FileCode 
Joe   | Shmoe  | XA22-573  | JS573 
John  | Doe   | EO11-123  | JD123 

Если это не ваш формат, вам мне нужно либо адаптировать мой код, либо ваш файл, либо и то, и другое.

Итак, как мы это сделаем? Сначала загрузите, сохраните и при необходимости разблокируйте скрипт до Import-XLS. Затем мы будем считать источник этого файла для загрузки функции в текущий сеанс PowerShell. Как только у нас будет функция, мы запустим ее и присвоим результаты переменной. Затем мы можем сделать пустую хэш-таблицу, и для каждой записи в импортированном массиве создайте запись в хэш-таблице, где свойство «Идентификатор» (в приведенном выше примере это будет тот, который имеет значение «EO11-123» в нем) , сделайте это ключом, а затем сделайте всю запись значением. Так, до сих пор мы имеем это:

#Load function into current session 
. C:\Path\To\Import-XLS.ps1 

$RefArray = Import-XLS C:\Path\To\file.xls 
$RefHash = @{} 

$RefArray | ForEach($RefHash.Add($_.Identifier, $_)} 

Теперь вы должны иметь возможность ссылаться на идентификатор, чтобы получить доступ к любому из свойств для соответствующей записи, такие как:

PS C:\> $RefHash['EO11-123'].FileCode 

JD123 

Теперь, нам просто нужно извлеките это имя из папки и переименуйте все файлы в нем. Довольно прямо отсюда.

Get-ChildItem c:\Path\to\Folders -directory | Where{$_.Name -match "(?<=)(\S+)$"}| 
    ForEach{ 
     $Files = Get-ChildItem $_.FullName 
     $NewName = $RefHash['$($Matches[1])'].FileCode 
     For($i = 1;$i -lt $files.count;$i++){ 
      $Files[$i] | Rename-Item -New "$NewName_$i" 
     } 
    } 

Edit: Хорошо, давайте сломаем процесс переименования здесь. Здесь много труб, поэтому я постараюсь сделать это шаг за шагом. Во-первых, у нас есть Get-ChildItem, который получает список папок для указанного вами пути. Эта часть достаточно прямая. Затем он ссылается на оператор Where, который фильтрует результаты, проверяя каждое имя, чтобы увидеть, соответствует ли оно регулярному выражению "(? < =) (\ S +) $". Если вы не знакомы с тем, как работают регулярные выражения, вы можете увидеть неплохую разбивку на https://regex101.com/r/zW8sW1/1. То, что это делает, соответствует любым папкам с более чем одним «словом» в имени и фиксирует последнее «слово». Он сохраняет это в автоматической переменной $Matches, и так как он захватил текст, который присваивается $Matches[1]. Теперь код здесь разрывается, потому что ваш CSV не выложен, как я предполагал, и вы хотите, чтобы файлы назывались по-разному. Мы должны будем внести некоторые корректировки «на лету».

Таким образом, те папки, которые проходят фильтр будет получать по трубопроводу в ForEach петлю (которая у меня была опечатка в ранее и имел ( вместо {, который сейчас исправлен). Поэтому для каждой из этих папок он начинается с получения списка файлов в этой папке и назначения их переменной $Files. Он также устанавливает переменную $NewName, но поскольку у вас нет столбца в CSV с именем FileCode, эта строка не будет работать для вас. Он использует автоматическую переменную $Matches, о которой я упоминал ранее, для ссылки на хеш-таблицу, которую мы настраиваем со всеми кодами идентификатора, а затем просматривает свойство этой конкретной записи, чтобы установить новое имя для назначения файлам. Поскольку то, что вы хотите и что я предполагал, различны, и ваш CSV имеет разные свойства, мы переработаем как предыдущий оператор Where, так и эту строку немного. Вот как это немного сценария теперь следующим образом:

Get-ChildItem c:\Path\to\Folders -directory | Where{$_.Name -match "^(.+?), .*? (\S+)$"}| 
    ForEach{ 
     $Files = Get-ChildItem $_.FullName 
     $NewName = $Matches[2] + "_" + $Matches[1] 

То, что сейчас совпадает с именем папки в Where заявлении и улавливает 2 вещи. Первое, что он захватывает, - это все в начале имени перед запятой. Затем он пропускает все, пока не получит последний фрагмент текста в конце имени и не захватит все после последнего пробела. Новый пробой на RegEx101: https://regex101.com/r/zW8sW1/2

Итак, вы хотите, чтобы ID_LName, которое можно получить из имени папки, действительно не нужно даже использовать ваш CSV-файл на данный момент, я не думаю. Мы создаем новое имя файлов, основанное на автоматической переменной $Matches, используя вторую группу захвата и первую группу захвата и помещая знак подчеркивания между ними. Затем мы просто перебираем файлы с помощью цикла For, основываясь на том, сколько файлов было найдено. Итак, мы начинаем с первого файла в массиве $Files (запись 0), добавляем это к $NewName с подчеркиванием и используем его для переименования файла.

+0

Можете ли вы сломать последнюю часть. Объясните, что все делает в части переименования скрипта? Я хочу понять это лучше. Я попытаюсь адаптировать ваш код, поскольку у меня есть только 3 столбца. FNAME, LNAME, Идентификатор. Я не вижу, как будет выглядеть NewName. Я буду переименовывать в: «LNAME_IAD» –

+0

Получил хэш. Теперь мне просто нужно ответить на вопрос 1 выше о том, что делает переименование. Он находит мои файловые папки с идентификатором и переименовывает файлы под ним.Проблема заключается в том, что он не переименовывает их в «Identifier_LastName.pdf» –

+0

Извините, сегодня я пришел в работу, поэтому у меня не было шанса действительно посмотреть на это до сих пор. Позвольте мне отредактировать мой ответ, чтобы узнать, могу ли я лучше объяснить часть переименования. – TheMadTechnician

Смежные вопросы