2015-12-09 2 views
3

У меня есть каталог назовём его C: \ MoveFile в этом каталоге находятся тысячи файлов одноименныхPowershell Move самый последний файл

  • Имя Дата Модифицированные
  • Dog_123123_Grey.doc 18/11/2015
  • Dog_123123_Grey (2) .doc 19/11/2015
  • Dog_123123_Grey (3) .doc 17/11/2015
  • Cat_123123_Blue (3) .doc 01/01/2015
  • Cat_123123_Pink (6) .doc 07/04/2015
  • Cat_123123_Pink (7) .doc 10/04/2015

Теперь, если номер версии в имени файла последовательно пронумерованы (2) и т.д. было бы быть легким, однако то, что я хочу сделать, - это запустить powershell через элементы в каталоге и перенести самый последний файл на основе даты, измененной в новое местоположение файла, чтобы из списка при условии, что новый каталог будет содержать.

Имя Дата Modified

  • Dog_123123_Grey (2) .doc 19/11/2015
  • Cat_123123_Blue (3) .doc 01/01/2015
  • Cat_123123_Pink (7) .doc 10/04/2015

Теперь, насколько моя голова может получить с этим,

gci C:\MoveFile\*.doc | sort LastWriteTime -desc | select -first 1 | cpi -dest c:\NewDirectory 

Что я не тестировал, поскольку я знаю, что он не является полным и не будет делать то, что мне нужно, чтобы быть честным, я знаю, что мне почему-то нужно игнорировать все, что находится в скобках, например. (3), который я не знаю, как это сделать. Я подумал о том, чтобы «как-то» смотреть только на первые 15 цифр, но некоторые из имен файлов могут быть длиннее или короче этого.

Поцарапав голову от разочарования, у кого больше опыта, чем у меня есть идеи?

+0

Я не понимаю логику ваших двух файлов «кошка» в вашем результате. –

ответ

3

Что вы можете сделать, это:

  1. группы файлов по имени (за исключением версии в имени файла)
  2. Сортировка файлов в каждой группе индивидуально
  3. Выберите самый последний из каждой группы

Чтобы получить имя файла без номера версии, мы можем использовать -replace регулярное выражение оператора, чтобы удалить любой набор скобок, содержащих одну или несколько цифр в конце BaseName строки (имя файла exlcuding расширения файла):

PS C:\> 'Cat_123123_Blue (3)' -replace '\(\d+\)$','' 
Cat_123123_Blue 

Таким образом, чтобы сгруппировать их по этой строке, мы делаем:

$FileGroups = Get-ChildItem -Path C:\Movefile\ -Filter *.doc |Group-Object { ($_.BaseName -replace '\(\d+\)$','').Trim() } 

затем перебрать наш массив групп:

$FileGroups |ForEach-Object { 
    # Sort each group, grab the most recent file 
    $RecentFile = $_.Group |Sort-Object LastWriteTime -Descending |Select -First 1 # Copy it 
    Copy-Item $RecentFile.FullName -Destination C:\NewFolder\ 
} 
+0

Хехе очень близко к моему подходу :) – sodawillow

+0

Великие мысли думают одинаково;) –

+0

_Beat me to it_ ^^ – sodawillow

4

Если я правильно понимаю вашу потребность, вот скрипт, который поможет вам перечислить файлы для перемещения (PS 3.0 необходим для параметра -FileGet-ChildItem).

Здесь я создаю новое свойство Group, в котором я удаляю «номер версии», чтобы получить своего рода «ключ» для группировки элементов.

Я перечисляю файлы, сортирую их по убыванию LastWriteTime, а затем группирую их по Group и беру первый элемент каждой группы.

$sourceFolder = "C:\MoveFile" 

$files = Get-ChildItem $sourceFolder -File | 
    Sort-Object LastWriteTime -Descending | 
    Select-Object *,@{ n = "Group"; e = { $_.Name -replace "\s\(\d+\)","" } } 

$filesToMove = $files | Group-Object Group | % { 
    $_.Group | Select-Object -First 1 
} 

$filesToMove | Select-Object Name,LastWriteTime 
+0

Черт, избили меня :) –

2

Я играл немного дольше, чем другие ребята, но пришли к такому же выводу:

$Folder = '\\Folder' 
$Groups = Get-ChildItem -Path $Folder | Group-Object -Property {($_.Name -replace "\s\(\d+\)","")} 

Foreach ($G in $Groups) { 
    $G | Select-Object -ExpandProperty Group | 
     Sort-Object LastWriteTime -Descending | Select -First 1 
} 

Хехе, лучше поздно, чем никогда: P

+0

Черт, не больше голосов за сегодня:) 'Group-Object {... } 'roxxx! Вы оба научили меня сегодня очень хорошо! Спасибо ^^ – sodawillow

+0

Без проблем, рад, что вам понравилось :) – DarkLite1