У меня есть каталоги, чьи имена являются временными метками, которые даны в миллисекундах с 1970-01-01:
1439715011728
1439793321429
1439879712214
.
.
И мне нужен вывод, как:
1442039711 Sat Sep 12 08:35:11 CEST 2015
1442134211 Sun Sep 13 10:50:11 CEST 2015
1442212521 Mon Sep 14 08:35:21 CEST 2015
.
.
Я могу перечислить все каталоги по команде:
find ./ -type d | cut -c 3-12
Но я не могу поместить вывод в следующую команду: date -d @xxxxxx
и манипулировать выводом.
Как я могу это сделать?
Fri Oct 2 05:35:28 47592
)Ответы:
Вы находитесь на правильном пути (для более простого решения, запустив только 2 или 3 команды, см. Ниже). Вы должны использовать
*
вместо того,./
чтобы избавиться от текущего каталога¹, и это несколько упрощает вырезание миллисекунд, а затем просто передать результат в GNUparallel
илиxargs
²:получить
и добавить смещение секунд до этого, как показывает ваш пример:
или:
получить:
Однако это проще сделать³:
который получит вам тот же запрошенный вывод еще раз.
Недостатком использования
*
является то, что вы ограничены командной строкой для ее расширения, однако преимущество заключается в том, что вы получаете каталоги, отсортированные по значению временной метки. Если количество каталогов является проблемой, используйте-mindepth 1
, но потеряете порядок:и вставьте,
sort
если необходимо:¹ Это предполагает, что нет вложенных подкаталогов, как это, кажется, имеет место из вашего примера. Вы можете также использовать
./ -mindepth 1
вместо*
² Вы можете заменить
parallel
сxargs -I{}
здесь @hobbs и @don_crissti предложил, он просто более многословным. ³ основываясь на ответе Жиля, чтобы использоватьdate
возможности чтения файловисточник
xargs
если у вас нетparallel
, что многие люди, вероятно, не имеют.xargs
не имеет возможности указать, куда идет аргумент, какparallel
с{}
.find ./ -type d | cut -c 3-12 | xargs -I{} date --d @{} +'%Y-%m-%d'
-I
опцию.--d
или--da
будет работать с текущими версиями GNUdate
, но он может перестать работать, когда деньdate
вводит--dalek
опцию (для дат в календаре Dalek).Я бы не использовал несколько команд на файл в цикле. Поскольку вы уже используете GNUisms:
Который просто запускает две команды.
strftime()
специфичен для GNU, вродеdate -d
.источник
У тебя уже есть:
который предположительно получает вам метки времени в формате эпохи. Теперь добавьте цикл while:
Обратите внимание, что в некоторых оболочках этот синтаксис получает цикл while в подоболочке, что означает, что если вы попытаетесь установить переменную там, она не будет видна после того, как вы покинете цикл. Чтобы это исправить, нужно слегка повернуть вещи с ног на голову:
который ставит
find
в подоболочку и поддерживает цикл while в основной оболочке. Этот синтаксис (AT & Tksh
,zsh
иbash
специфический) нужен только если вы хотите повторно использовать результат внутри цикла, однако.источник
done <(find)
вместо этогоdone < <(find)
оно было правильнымyash
(где<(...)
перенаправление процесса, а не подстановка процесса), поэтому мое редактирование было немного кавалернее, поскольку это могла быть оболочка, для которой вы имели в виду.Если у вас есть GNU date, он может конвертировать даты, прочитанные из входного файла. Вам просто нужно немного помассировать временные метки, чтобы они могли их распознать. Синтаксис ввода для временной метки, основанной на эпохе Unix,
@
сопровождается числом секунд, которое может содержать десятичную точку.источник
date
чтение файла. Это дастdate: invalid date ‘@’
из-за перевода текущего каталога (./
). А так как вы можете отбросить миллисекунды, вы можете упростить второеsed
редактирование, просто отбросив последние 3 символа. Или удалите все это и используйтеfind * -type d -printf "@%.10f" | date ...
Я бы сделал это с удовольствием - подпишите список временных меток:
Это выводит:
Если вы хотите определенный выходной формат, вы можете использовать,
strftime
например:Что превратить это в один вкладыш в вашей трубе:
Но я бы посоветовал вместо этого взглянуть на использование
File::Find
модуля и сделать все это в Perl. Если вы приведете пример своей структуры каталогов, прежде чем разрезать ее, я приведу вам пример. Но это было бы что-то вроде:источник
С
zsh
и встроенный strftime :это предполагает, что все ваши имена каталогов в текущем каталоге на самом деле являются эпохами.
Дальнейшая фильтрация / обработка возможна при условии, что вы укажете, как должны обрабатываться эти числа в вашем примере (они больше похожи на времена эпохи, соответствующие датам рождения принцессы Леи и Люка Скайуокера ...), например, рекурсивно ищите имена каталогов, которые соответствуют по крайней мере 10 цифр и рассчитать дату на основе первых 10 цифр:
источник
Использование GNU Parallel:
Если вы можете принять \ t вместо пробела:
источник
parallel
написано вperl
. Это кажется излишним, учитывая, чтоperl
естьstrftime()
оператор. Нравитсяperl -MPOSIX -lpe '$_.=strftime(" %c", localtime substr $_, 2, 10)'
parallel
. IMO,parallel
это отличный инструмент для распараллеливания задач, интенсивно использующих процессор, но он не совсем подходит для такого рода задач.Обычно команда find может быть связана с любой командой, использующей
exec
аргумент.В вашем случае вы можете сделать так:
источник
Использование Python (это наиболее медленное решение)
дает:
источник