Что предложенный Gilles является, вероятно, лучшим ответом, если возможно сделать.
Если бы это не, обходное решение, которое должно работать, должно было бы использовать управление x-мыши для отправки ключей стрелки вверх и вниз каждый раз, когда мышь прокручивается. Я никогда не использовал экраны со шпаклевкой, но я использовал эту установку на шпаклевке в окнах, чтобы смочь просмотреть текстовый файл путем прокрутки с vi или нано. У меня была другая установка профилей, один для 3 прокруток строки и один для 1 прокрутки строки.
Можно использовать touch -r
использовать метку времени другого файла вместо текущего времени (или touch --reference=FILE
)
Вот два решения. В каждом решении первая команда изменяет время изменения каталога к тому сразу из новейшего файла под ним, и вторая команда смотрит на целое дерево каталогов рекурсивно. Изменитесь на каталог (cd '.../(1997-05-20) The Colour and The Shape'
) прежде, чем выполнить любую из команд.
В zsh (удаляют D
проигнорировать точечные файлы):
touch -r *(Dom[1]) .
touch -r **/*(Dom[1]) .
На Linux (или в более общем плане с GNU находят):
touch -r "$(find -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' |
sort |tail -n 1 | cut -d= -f2-)" .
touch -r "$(find -mindepth 1 -printf '%T+=%p\n' |
sort |tail -n 1 | cut -d= -f2-)" .
Однако обратите внимание, что те не принимают символов новой строки в именах файлов.
Это не "рекурсивно", это просто изменяет все метки времени в папке. Если это - то, что Вы имеете в виду, существует два шага.
stat -c '%Y' filename
произведет метку времени filename
, и stat -c '%Y %n' *
произведет метку времени и имя файла каждого файла в папке, таким образом, это найдет имя файла последний раз измененного файла в текущей папке:
mostrecent="`stat -c '%Y %n' * | sort -n | tail -n1 | cut -d ' ' -f '2-'`"
Вообще-то, если задуматься существует путь более легкий способ получить самую высокую метку времени в папке:
mostrecent="`ls -t | head -n1`"
Затем Вы хотите изменить все файлы в папке, чтобы иметь ту же метку времени как тот файл. touch -r foo bar
изменится bar
иметь ту же измененную метку времени как foo
, таким образом, это изменит все файлы в папке, чтобы иметь ту же измененную метку времени как Ваш последний раз измененный файл:
touch -r "$mostrecent" *
Так, острота:
touch -r "`ls -t | head -n1`" *
ls
имена файлов искажений, содержащие символы неASCII. Если Вы хотите остроты, используйте zsh:-),
– Gilles 'SO- stop being evil'
03.09.2010, 00:42
Я соединил работу и теперь:
Это было бы сценарием, который изменяет все каталоги внутри /tmp/test/
к метке времени новейшего файла в каждом каталоге:
#!/bin/bash
if [ -z "$1" ] ; then
echo 'ERROR: Parameter missing. specify the folder!'
exit
fi
#MODE=tail # change to newest file
MODE=head # change to oldest file
for d in "$1"/*/; do
echo "running on $d"
find "$d" -type d -execdir \
echo touch --reference="$(find "$d" -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' \
| sort | "$MODE" -n 1 | cut -d= -f2-)" "$d" \;
# remove echo to really run it
done
можно добавить некоторые файлы тестирования в/tmp как это:
mkdir /tmp/test
cd /tmp/test
mkdir d1
mkdir d2
touch d1/text1.txt
sleep 1
touch d1/movie1.mov
touch d2/movie2.mov
sleep 1
touch d2/text2.txt
touch notthis.file
"
снова, это сначала смотрит, как он отсутствует, но это работает.
– rubo77
16.08.2013, 23:51
Мне не очень понравилась неясность shell-команд, и я быстро сделал это в python.
Он рекурсивно устанавливает mtimes всех каталогов на самый новый неисключенный файл/дир mtime внутри.
import os
import sys
EXCLUDE_FILES = ['.DS_Store']
EXCLUDE_DIRS = ['.git', '.hg']
def inheritMTime(path):
for root, dirs, files in os.walk(path, topdown=False, followlinks=False):
currentMaxMtime = None
for subpath in files:
if subpath in EXCLUDE_FILES:
print "ignore file", os.path.join(root, subpath)
continue
currentMaxMtime = max(currentMaxMtime, os.lstat(os.path.join(root, subpath)).st_mtime)
for subpath in dirs:
if subpath in EXCLUDE_DIRS:
print "ignore dir", os.path.join(root, subpath)
continue
currentMaxMtime = max(currentMaxMtime, os.lstat(os.path.join(root, subpath)).st_mtime)
if currentMaxMtime is not None:
os.utime(root, (currentMaxMtime, currentMaxMtime))
if __name__ == "__main__":
for dir in os.listdir(sys.argv[1]):
if os.path.isdir(dir):
current = os.path.join(sys.argv[1], dir)
inheritMTime(current)
Я использую этот скрипт для рекурсивной установки меток времени папок для последнего содержимого. (Это очень похоже на ответ Жиля):
#! /bin/bash
# Change mtime of directories to that of latest file (or dir) under it, recursively
# Empty leaf directories, or dirs with only symlinks get the $default_timestamp
default_timestamp='1980-01-01 00:00:00'
dir="$1"
[ -d "$dir" ] || { echo "Usage: $0 directory" >&2; exit 1; }
find "$dir" -depth -type d | while read d; do
latest=$(find "$d" -mindepth 1 -maxdepth 1 \( -type f -o -type d \) -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
if [ -n "$latest" ]; then
touch -c -m -r "$latest" "$d" \
|| echo "ERROR setting mtime of '$d' using ref='$f'" >&2
else
touch -c -m -d "$default_timestamp" "$d" \
|| echo "ERROR setting mtime of '$d' to default '$default_timestamp'" >&2
fi
done
Я взял команду @Gilles zsh и улучшил ее для работы с подпапками, но кажется, что zsh ужасно неэффективен для части **/ *(FDod ).
# Don't do this
for d in **/*(FDod); do touch -r "$d"/*(Dom[1]) "$d"; done
Кавычки позволяют корректно работать элементам каталога, содержащим пробелы и табуляции. FD заставляет его находить не -пустые каталоги, в том числе те, которые начинаются с., od заставляет его искать в глубине -первым способом, так что временные метки родительской папки обновляются должным образом.
При тестировании я заметил, что производительность и объем памяти для **/ *(FDod )были безумными (более 1,4 ГБ всего для 650 тыс. папок ), и перед запуском он читал все подряд трогать папки. После замены на find/read стал намного быстрее, не жрал память и запустился практически сразу.
#! /usr/bin/env zsh
# Do this instead
find "$@" -depth -type d ! -empty -print0 |while IFS= read -r -d ''; do
touch -r "$REPLY"/*(Dom[1]) "$REPLY"
done
Если вы не запускаете его в сценарии, замените «$@» папками, из которых вы хотите его запустить.
Я хотел обновить mtime
всех каталогов и файлов в определенном каталоге до текущей метки времени.
Вот что мне помогло-
# recursively update mtime on all directories
find./somedir -type d -exec touch -t $(date +%s) {} +
# recursively update mtimes on all files
find./somedir -type f -exec touch {} +
/media/media/MP3s
? Затем в zsh:for d in /media/media/MP3s/**/*(/); do touch -r $d/*(Dom[1]) $d; done
. Без zsh (но действительно, используйте zsh, это просто более просто): поместите команду в сценарий и работайтеfind /media/media/MP3s -type d -execdir /path/to/the/script \;
. – Gilles 'SO- stop being evil' 03.09.2010, 10:10for d in ...
как можно адаптировать следующее, таким образом, это будет также работать с папками, которые содержат пробелы? (который все еще отсутствует в моем решении), – rubo77 16.08.2013, 14:36