Мне нужно было отобразить список каталогов, отсортированных по дате создания, и я придумал этот фрагмент кода, который я посчитал довольно умным. Есть ли более очевидный способ сделать это, который я упускаю?
printf "%-20s\t\t\t%-s\n" "DATE" "CASE"
printf "%-20s\t\t\t%-s\n" "----" "----"
find $idir -mindepth 3 -maxdepth 3 -type d -printf "%T@ %Tc\t\t%p\n" \
| sed "s#${idir}/##" \
| sort -h \
| sed "s#^[^ ]* ##"
Пример вывода
DATE CASE
---- ----
Fri 06 Sep 2013 11:17:41 AM EDT dir1/Baseline/2013_09_06_11_16_10
Fri 06 Sep 2013 01:44:38 PM EDT dir2/Baseline/2013_09_06_13_42_48
Sun 08 Sep 2013 05:02:46 PM EDT dir3/6 Month/2013_09_08_17_02_05
Fri 13 Sep 2013 02:28:30 PM EDT dir4/Baseline/2013_09_13_14_25_09
Подробности
Вышеуказанный код будет искать ровно 3 каталога в глубину от каталога $idir
. Затем он выводит время создания всех каталогов, которые находятся на этой глубине. Затем я удаляю часть $idir
пути из вывода (она не нужна), сортирую его, а затем отсекаю %T@
часть вывода. Это было сделано только для того, чтобы мне было легче сортировать вывод.
Без завершающего символа sed
вывод выглядит так:
DATE CASE
---- ----
1378480661.2612650000 Fri 06 Sep 2013 11:17:41 AM EDT dir1/Baseline/2013_09_06_11_16_10
1378489478.3223970000 Fri 06 Sep 2013 01:44:38 PM EDT dir2/Baseline/2013_09_06_13_42_48
1378674166.7427782000 Sun 08 Sep 2013 05:02:46 PM EDT dir3/6 Month/2013_09_08_17_02_05
1379096910.4431689000 Fri 13 Sep 2013 02:28:30 PM EDT dir4/Baseline/2013_09_13_14_25_09
Покажите мне более чистый метод!
решение1
Нет хорошего, переносимого метода сортировки файлов по времени. Наиболее переносимыми методами являются:
- Если вы можете предположить, что имена файлов содержат только печатные символы, вызовите
ls -ltd
. - В противном случае используйте perl.
Это классический метод сортировки файлов по дате с помощью инструментов GNU. Вы предполагаете, что имена файлов не содержат символа новой строки; это легко исправить, изменив \n
на \0
и вызвав sort
с -z
опцией. О, и отбросьте обходные sed
вызовы; обратите внимание, что ваш скрипт не будет работать, если $idir
содержит любой из #*^$\[
, потому что sed интерпретирует их как специальные символы.
cd "$idir" &&
find -mindepth 3 -maxdepth 3 -type d -printf '%T@ %Tc\t\t%p\0' |
sort -hz |
tr '\0\n' '\n\0' |
sed 's/^[^ ]* //'
Кстати, вы сортируете файлы по времени их изменения, а не по времени создания. Большинство вариантов unix, кроме OSX, не поддерживают время создания на всем протяжении (от файловой системы через ядро до пользовательских инструментов).
Простой и понятный способ сортировки файлов по времени их изменения — использовать zsh. Квалификатор glob om
сортирует файлы по возрастанию возраста (используйте, Om
чтобы получить сначала самый старый файл).
files=(*(om))
echo "The oldest file is $files[-1]"
Чтобы получить вывод, подобный показанному вами, вы можете использоватьzstat
.
zmodload zsh/stat
describe () {
typeset -A st
zstat -s -H st "$REPLY"
echo "$st[mtime] $REPLY"
}
: */*/*(/+describe)