Як переміщувати файли на основі року


15

Мені потрібно переміщувати файли на основі року. Я використав findкоманду

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

але для успішного виконання цієї команди мені потрібно точно знати mtimeзараз 470 - лише здогадка. Значить, якщо я можу дати 2012 рік, він дає мені файли, пов'язані лише з 2012 роком.

Тож мені потрібна порада, як це зробити

Знайдіть файли на основі року, наприклад, 2012 року та перемістіть їх до іншого каталогу.

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 

Чи має сенс використовувати -exec ls ... \;замість -exec ... +? Ваша знахідка для цього занадто стара? У цьому випадку find ... -print0 | xargs -0 ls...було б набагато швидше.
Hauke ​​Laging

Я хотів би, щоб ці питання (і відповіді), які стосуються ядерних програм, зазвичай визначали, чи маємо ми справу з GNU або BSD (або іншими) утилітами.
лабіринт

Відповіді:


39

Ви хочете скористатися -newermtопцією для find:

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

щоб отримати всі файли з часом модифікації в 2012 році.

Якщо ваша знахідка не підтримує, -newermtви також можете зробити наступне, щоб запобігти використанню компенсованих обчислень:

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref

1
-newermt прапор недоступний у команді Find
OmiPenguin

Це, мабуть, є старою версією висновку, з яким постачається ваш RHEL? Я дам альтернативу у відповідь на це
Антон

Так, це 5.2
OmiPenguin

Я вважаю, що це перегляд RHEL, а не find(я знайду версію 4.4.2)
Антон

1
Перемикач newermt не з’явився в пошуку до версій після версії v4.3.3, gnu.org/software/findutils/manual/html_mono/find.html .
slm

5
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls не має жодного сенсу.


1
-exec ls -lмає більше сенсу і навіть більше під час тестування.
CVn

@ MichaelKjörling findможе надрукувати все, що lsможе. Гаразд, за одним винятком: втеча / цитування неприємних ознак. Але загалом вихід findможна сортувати безпосередньо. Марні дзвінки ЛС не роблять все це швидше.
Hauke ​​Laging

Я дуже часто використовую щось досить схоже (хоча особисто я вважаю за краще -printчи можливо -ls ) під час тестування. Перевага використання -exec ls {}полягає в тому, що він вже виконує щось зовнішнє для пошуку . Так що на той час , коли ви перемикатися з lsна mvфактичні зміни мінімальні.
CVn

3

Відповідно до сторінки man, аргумент до -mtime - це кількість днів, яку ви шукаєте. Ви можете date +%jзнайти кількість днів з 1 січня поточного року.


2
Гарний спосіб. Щоб бути дуже "nitpicky": -mtime -1: це будь-який файл за останні 24 години. Не лише файли з вчорашнього дня (або сьогодні). Отже, також буде невелике «перекриття»: якщо ви визначите, що минуло 120 днів з 2012 року, а сьогодні це 15:45, коли ви запускаєте сценарій, ви в кінцевому підсумку виберете файли до 31 грудня 15:45 ( а не останні в той день) ... Ви, ймовірно, можете використовувати: nb_day - 1, а потім "відрізати" кілька тих, хто датується 2013 роком (їх можна знайти ls -l | grep -v, АЛЕ вихід відрізняється, якщо їм лише 1 день ... багато підводних каменів ...)
Олів'є Дулак

Ви хочете використовувати цю -daystartопцію, якщо збираєтесь працювати -mtime. Інакше у вас виникнуть проблеми з файлами на початку та в кінці року, яким би ви не зверталися, якщо не запустити це точно о півночі. Ви можете зробити компенсацію точніше, -mminніж за допомогою, -mtimeякщо зможете легко знайти кількість хвилин з нового року. Але така ж проблема існує і з цим, як і з -mtimeменшою кількістю файлів (ці хвилини близько півночі).
Антон

1
Так, перечитуючи сторінку чоловіка, я бачу, як вона розбивається на години, тож просте, find -mtime $("date -+%j")мабуть, не дасть ОП те, на що вони йдуть. Я залишаю це для нащадків, хоча, оскільки це здається можливим сліпою плямою, в яку люди можуть потрапити.
Братчлі

2

Ви можете спробувати використати комбінацію з командами statта / або dateкомандами, як у наступних одностроях:

BSD / Mac OS X:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

Linux:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

В обох випадках підхід полягає у використанні dateкоманди для вилучення року з останнього часу модифікації кожного файлу, а потім для побудови шляху до цього року. Команда mkdir -pстворить цей шлях, якщо він ще не існує. Звичайно, ви можете скористатися деякими іншими findпараметрами для уточнення пошуку.


1

Якщо це зробити з робочого каталогу, ви можете зробити це замість цього:

ls -l |awk '{ if ($8 == "2013") print $9 }'

Це значно спрощує речі і не спричиняє перекриття. Але також передбачається, що ці файли старше 6 місяців, і вони lsбудуть друкувати рік замість точного часу.

Для файлів, які перевищують 6 місяців, вам доведеться просто замінити його таким:

ls -l |awk '{ if ($6 == "May") print $9 }' 

чи щось подібне, залежно від місяця. Якщо ви хочете створити список місяців для переміщення файлів (або якщо ви хочете створити список протягом років), зробіть це:

month="May Jun Jul"; 
for i in `echo $month`; 
do 
    for j in `ls -l |awk '{ if ($6 == "'$i'") print $9}'`
    do
        mkdir -p $i
        mv $j $i
    done
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.