Скрипт Bash / DOS / PowerShell для отображения последних версий файлов? - PullRequest
5 голосов
/ 06 февраля 2009

У нас есть список (скажем, 50) отчетов, которые выгружаются в различные папки в зависимости от определенных условий. Все отчеты имеют стандартные названия, например. D099C.LIS, D18A0.LIS и т. Д.

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

Я могу легко сделать это с помощью кода или перенаправить вывод «dir» или «ls» в текстовый файл, а затем манипулировать им в Excel, но я бы предпочел более простое (надеюсь, однострочное) решение либо с использованием DOS , bash или PowerShell.

Лучшее, что я когда-либо придумал в PowerShell (я сделал нечто подобное с помощью bash):

ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime

Это будет рекурсивно перечислять все файлы с расширением * .lis, затем сортировать их по имени (asc) и дате (desc), а затем отображать каталог, имя и дату.

Это дает такой вывод:

C:\reports\LESE            D057A.LIS                  28/01/2009 09:00:43
C:\reports\JCSW            D057A.LIS                  27/01/2009 10:50:21
C:\reports\ALID            D075A.LIS                  04/02/2009 12:34:12
C:\reports\JCSW            D075B.LIS                  05/02/2009 10:07:15
C:\reports\ALID            D075B.LIS                  30/01/2009 09:14:57
C:\reports\BMA3            D081A.LIS                  01/09/2008 14:51:36

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

C:\reports\LESE            D057A.LIS                  28/01/2009 09:00:43
C:\reports\JCSW            D075B.LIS                  05/02/2009 10:07:15
C:\reports\BMA3            D081A.LIS                  01/09/2008 14:51:36

У кого-нибудь есть идеи?

[править] Несколько хороших идей и ответов на этот вопрос. К сожалению, я не могу отметить все как принятые, но ответ EBGreen (отредактированный) работал без изменений. Я добавлю рабочие решения здесь, когда проверю их.

Баш:

 ls -lR --time-style=long-iso | awk 'BEGIN{OFS="\t"}{print $5,$6,$7,$8}' | grep ".LIS" | sort -k4 -k2r -k3r | uniq -f3
 ls -lR --time-style=long-iso | awk 'BEGIN{OFS="\t"}{print $5,$6,$7,$8}' | grep ".LIS" | sort -k4 -k2r -k3r | awk '!x[$4]++'

PowerShell:

  ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime | Group-Object Name | %{$_.Group | Select -first 1}
  ls -r . *.lis | sort -desc LastWriteTime | group Name | %{$_.Group[0]} | ft Directory,Name,LastWriteTime
  ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | unique | ft Directory,Name,LastWriteTime

Ответы [ 8 ]

8 голосов
/ 06 февраля 2009
ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime | Group-Object Name | %{$_.Group | Select -first 1}
2 голосов
/ 05 марта 2009

Еще одна альтернатива в PowerShell, более «сценарий», такой как:

ls -r . *.lis | sort LastWriteTime | %{$f=@{}} {$f[$_.Name]=$_} {$f.Values} | ft Directory,Name,LastWriteTime
  1. получить файлы рекурсивно
  2. сортировать их по возрастанию по времени последней записи
  3. инициализировать хэш-карту (ассоциативный массив)
  4. для каждого файла назначьте его, используя имя в качестве ключа - более поздние записи перезапишут предыдущие
  5. получить значения хеш-карты (исключая ключи)
  6. формат в виде таблицы

Обратите внимание, что объекты FileInfo сохраняются по всему конвейеру. Вы по-прежнему можете обращаться к любому свойству / методу объектов или форматировать их по своему усмотрению.

2 голосов
/ 06 февраля 2009

В bash вы можете передать свои ответы через uniq . Я не уверен в точной структуре результатов вашего bash 1-liner, но правильные аргументы для -w N и -s N должны это сделать.

1 голос
/ 05 марта 2009

Powershell:

ls -r . *.lis | sort -desc LastWriteTime | sort -u Name | ft Directory,Name,LastWriteTime

Пояснение:

  1. получить файлы рекурсивно
  2. сортировка файлов по убыванию LastWriteTime
  3. сортировать файлы по имени, выбирая уникальные файлы (только первые).
  4. форматирование получающихся объектов FileInfo в таблице с помощью Directory, Name и Time

Альтернатива, которая не зависит от стабильности sort :

ls -r . *.lis | sort -desc LastWriteTime | group Name | %{$_.Group[0]} | ft Directory,Name,LastWriteTime
  1. получить файлы рекурсивно
  2. сортировка файлов по убыванию LastWriteTime
  3. группировать файлы по имени
  4. для каждой группы выберите первый (индекс ноль) элемент группы
  5. отформатировать полученные объекты FileInfo в таблице с помощью Directory, Name и Time
1 голос
/ 06 февраля 2009

Похоже, проблема заключается в поиске уникального в зависимости от конкретной области. awk может быть использован для решения этой проблемы. Видел эту запись в блоге , которая имеет один подход. Например, в bash можно сделать:

найти. имя "* .lis" xargs ls -tr | awk -F / '! x [$ NF] ++'

0 голосов
/ 15 июля 2010

ls -ARFlrt | awk '{print $ 6, $ 7, $ 8}' | grep 2010 | sort -n

Искал подобное. Вышесказанное помогло мне получить список, в котором я участвовал в bash. Grep не является обязательным (конечно). \ Спасибо

0 голосов
/ 07 февраля 2009

$ f = ls -r -fi * .lis | имя сортировки, lastWriteTime -desc

# Remove-whatIf, чтобы удалить файлы

$ f [1 .. $ f.length] | Remove-Item-whatIf

0 голосов
/ 06 февраля 2009

Можете ли вы использовать Perl? Что-то вроде:

ваша команда | perl 'while () {($ dir, $ name, $ date) = split; $ hash {$ name} = ($ dir, $ date);} foreach (keys% hash) {print "$ hash {$ } [0] $ $ hash {$ _} [1] \ п "; } '

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

...