Пакет переименовывает файлы изображений возрастом плюс, добавляют дата и переменная к имени файла

Если файл сканирований всегда имеет то же имя / придерживается определенного шаблона, можно также настроить обнаружение типа файла; поместите следующее в Ваш ~/.vimrc:

:autocmd BufNew,BufRead SConstruct setf python
7
23.05.2017, 15:40
2 ответа

Забудьте о shred , он тратит много времени, делая бесполезные вещи и пропускает существенное.

shred стирает файлы, совершая многократные проходы перезаписи файлов случайными данными (a «Gutmann wipe»), потому что с дисковыми технологиями 20-30-летней давности и некоторым дорогим лабораторным оборудованием удалось (по крайней мере в теории) восстановить перезаписанные данные. Это уже не относится к современным дисковым технологиям: перезапись только один раз нулями так же хороша - но идея множественных случайных проходов сохранилась хорошо после того, как она устарела. См. https://security.stackexchange.com/questions/10464/why-is-writing-zeros-or-random-data-over-a-hard-drive-multiple-times-better-th

С другой стороны, shred полностью не очищает конфиденциальную информацию, поскольку стирает только те данные в файлах, которые требуется стереть. Любые данные, сохраненные в ранее стертых файлах, по-прежнему могут быть восстановлены путем прямого доступа к диску, а не через файловую систему. Данные из гит-дерева может быть не очень легко восстановить; тем не менее это реальная угроза.

Чтобы быстро удалить часть данных, зашифруйте их. Можно использовать ecryptfs (шифрование домашнего каталога), или encfs (шифрование дерева каталогов), или dm-crypt (шифрование всего раздела), или любой другой метод. Чтобы стереть данные, просто протрите ключ.

См. также Как убедиться, что каталог или файл действительно удален?

-121--120372-

Существует множество способов для этого. Например, файл

  • grep

     grep -oP 'BIG\* 20021208\* 00001\* *\K [A-Z0-9-] +'
    

    Объяснение

    -o делает печать grep только соответствующей частью строки, а -P активирует синтаксис Perl Compatible Regular Expression (PCRE). \K в PCRE приводит к тому, что все, что было сопоставлено до этой точки, отбрасывается (и, следовательно, не печатается, из-за -o ). [A-Z0-9-] - класс символов , который соответствует любой заглавной букве от A до Z, любому числу или - и который может повторяться один или несколько раз ( + ).

    Если целевая последовательности также может содержать строчные буквы, просто запустите grep с флагом -i или измените класс символов на [a-zA-Z0-9-] .

    --- или ---

     grep -oP 'BIG\* 20021208\* 00001\* *\K. + (? =...)' файл
    

    Объяснение

    Это так же, как выше только здесь, есть положительный взгляд вперед ( (? =...) ), что означает, что . + будет совпадать только если предшествовать ... .

  • sed

     sed -rn 's/...//g; s/. * BIG\* 20021208\* 00001\* *//p;' файл
    

    Объяснение

    Оператор s/from/to/ является оператором замещения sed. Он заменяет с на на . Первый заменяет ... ничем, он удаляет их ( g обеспечивает это для всех матчей на линии). Второй удаляет все от начала строки (. * ) до BIG * 20021208 * 00001 ( * имеет особое значение в регулярных выражениях, поэтому его нужно отделить от \* ), затем 0 или более звездочек (\* * ). Вместе они удаляют все, кроме того, что вы хотите.

    -n подавляет печать любого выходного сигнала. p в конце 2-го оператора подстановки заставляет sed печатать любую ложь, где подстановка была успешной.

  • awk

     awk -F '[*...]' Файл '/BIG\* 20021208\* 00001\* */{ print $ (NF-1)} '
    

    Пояснение

    -F устанавливает разделитель поля ввода в * или ... . Это означает, что предпоследнее поле будет нужным. Команда, приведенная выше, печатает ее в строках, соответствующих BIG * 20021208 * 00001 * .

  • Perl

     perl -lne '/BIG\* 20021208\* 00001\* * (. *) .../& & напечатать файл «$1» '
    

    Объяснение

    -n заставляет perl считывать свои входные строки по строкам и применять к ним сценарий, заданный -e . -l добавляет символ новой строки к каждому вызову print . Команда, приведенная выше, попытается сопоставить интересующую последовательность (см. пояснение к приведенному выше примеру sed) и напечатать ее в случае успешного выполнения.

    Можно также использовать тот же подход, что и в примере с неловкостью:

     perl -F '[*...]' -lane '/BIG\* 20021208\* 00001\* */& & напечатать файл «$ F [$ # F]» '
    
-121--202656-

В большинстве уникций не отслеживается дата создания файла «». «Дата создания» в любом случае не определена (копирование файла создает новый файл?). Можно использовать время изменения файла, которое определяется разумной интерпретацией даты создания последней версии данных. При создании копий файла необходимо сохранить время изменения (например, cp -p или cp -a при использовании команды cp , а не команды cp ).

Несколько форматов файлов имеют поле в файле, где автор приложения заполняет дату создания. Это часто относится к фотографиям, где камера заполняет некоторые данные Exif на изображениях JPEG или TIFF, включая время создания. Формат изображения Nikon NEF охватывает TIFF и также поддерживает Exif.

Имеются готовые инструменты для переименования файлов изображений, содержащих данные Exif, для включения даты создания в имя файла. переименование изображений для включения даты создания в имя показывает два решения: exiftool и exiv2 .

Я не думаю, что ни один из инструментов позволяет включить счетчик в имя файла. Переименование можно выполнить за два прохода: сначала включить дату (с максимально высоким разрешением для сохранения порядка) в имя файла, затем пронумеровать файлы в соответствии с этой деталью даты (и отбросить время). Поскольку современные DSLR могут возбуждать всплески изображений (Nikon's D4s снимает на 11fps) желательно сохранить исходное имя файла также на первой фазе, так как в противном случае это потенциально привело бы к нескольким файлам с одним и тем же именем файла.

exiv2 mv -r %Y%m%d-%H%M%S:basename: *.NEF
# exiv2 uses `strftime(3)`, so `%Y%m%d-%H%M%S` returns YYYYMMDD-hhmmss
# :basename: is a naming variable exiv2's `-r`-handle provides. See `exiv2 -h` for more  
# Now you have files with names like 20140630-235958_DSCC1234.NEF.
# Note that chronological order and lexicographic order agree with this naming format.
i=10000
for x in *.NEF; do
  i=$((i+1))
  mv "$x" "${x%-*}_FOO_${i#1}.NEF"
done

$ {x% - *} удаляет деталь после символа - . Переменная счетчика i отсчитывается от 10000 и используется с первой цифрой 1 ; это хитрость, чтобы получить начальные нули, чтобы все значения счетчиков имели одинаковое число.

Переименование файлов путем увеличения числа в имени файла имеет другие решения для переименования набора файлов, чтобы включить счетчик.

Если вы хотите использовать временную метку файла, а не данные Exif, см. Переименование набора файлов с измененной датой в конце имени файла?


Как правило, не создавайте код оболочки и не направляйте его в оболочку. Это излишне запутанно. Например, вместо

find -name '*.NEF' | 
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' | 
bash

можно написать

find -name '*.NEF' | 
gawk 'BEGIN{ a=1 }{ system(sprintf("mv %s %04d.NEF\n", $0, a++)) }'

Обратите внимание, что обе версии могут привести к катастрофическим результатам, если имя файла содержит специальные символы оболочки (например, места, ', $ , ' и т. д.), поскольку имя файла интерпретируется как код оболочки. Есть способы превратить это в надежный код, но это не самый простой подход, поэтому я не буду придерживаться этого подхода.


start Обратите внимание, что существует что-то называемое «ctime», но c не для создания , это для изменения . ctime изменяется каждый раз, когда что-либо меняется в файле, либо в его содержимом, либо в метаданных (имя, разрешения,...). ctime в значительной степени является антитезой времени создания.

8
27.01.2020, 20:16
stat --printf='}" "%z_${SN}_${LINENO}"\n' -- * | 
nl -nln -w1 -s '' |
sort -k2,3 | 
sed 's| ..:[^_]*||;s|-||g;s|^|echo mv "${|' |
SN=SHOOTNAME sh -s -- *

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

Он работает путем * подстановки всех файлов в текущем каталоге и вывода времени их изменения. Для файлов в текущем каталоге, содержащих суффикс .NEF , вам нужно изменить * globstar на концах обеих строк 1 и 5 на *. NEF . Он добавляет в конец некоторые переменные оболочки и кавычки - имена для которых существуют только на другом конце конвейера в подоболочке sh .

Кроме того, поскольку мы указываем имена файлов только в соответствии с их порядком глобализации или параметрами типа оболочки $ {1} , это отлично работает с любым именем файла - какими бы странными символами оно ни было.

На данный момент команда включает echo - это ослаблено. Бег, по сути, бесполезен - он просто показывает вам, что он хочет делать. Вот его вывод из моего домашнего каталога перед его загрузкой в ​​ sh :

echo mv "${2}" "20140611_${SN}_${LINENO}"
echo mv "${4}" "20140614_${SN}_${LINENO}"
echo mv "${11}" "20140617_${SN}_${LINENO}"
echo mv "${7}" "20140622_${SN}_${LINENO}"
echo mv "${8}" "20140622_${SN}_${LINENO}"
echo mv "${1}" "20140624_${SN}_${LINENO}"
echo mv "${10}" "20140704_${SN}_${LINENO}"
echo mv "${5}" "20140704_${SN}_${LINENO}"
echo mv "${9}" "20140704_${SN}_${LINENO}"
echo mv "${12}" "20140705_${SN}_${LINENO}"
echo mv "${3}" "20140705_${SN}_${LINENO}"
echo mv "${13}" "20140706_${SN}_${LINENO}"
echo mv "${6}" "20140706_${SN}_${LINENO}"

Вот он после sh :

mv Desktop-1 20140611_SHOOTNAME_1
mv Library 20140614_SHOOTNAME_2
mv target.txt 20140617_SHOOTNAME_3
mv script.sh 20140622_SHOOTNAME_4
mv script.sh~ 20140622_SHOOTNAME_5
mv Desktop 20140624_SHOOTNAME_6
mv shot-2014-06-22_17-11-06.jpg 20140704_SHOOTNAME_7
mv Terminology.log 20140704_SHOOTNAME_8
mv shot-2014-06-22_17-10-16.jpg 20140704_SHOOTNAME_9
mv test 20140705_SHOOTNAME_10
mv Downloads 20140705_SHOOTNAME_11
mv test.tar 20140706_SHOOTNAME_12
mv new
file 20140706_SHOOTNAME_13

Вы могли заметить, что мой вывод показывает несколько файлов изображений, уже названных на время их создания, но их новое присвоенное имя не совпадает. Это не результат сортировки , которая работает, как предписано, а скорее то, что эти файлы в последний раз меняли статус в эту дату. Тем не менее, как вы указали в комментариях к этому вопросу ctime - это свойство, которое вы ищете, то есть свойство сортировки и имени, предлагаемое здесь. Тем не менее, вот результат stat с прикрепленными именами файлов:

stat -c '%z %n' -- *

2014-06-24 16:50:09.110283839 -0700 Desktop
2014-06-11 23:34:02.981981145 -0700 Desktop-1
2014-07-05 01:00:43.213344635 -0700 Downloads
2014-06-14 10:32:13.537014418 -0700 Library
2014-07-04 23:02:25.079690701 -0700 Terminology.log
2014-07-06 11:24:05.398936386 -0700 new
file
2014-06-22 11:26:53.658004123 -0700 script.sh
2014-06-22 11:26:53.658004123 -0700 script.sh~
2014-07-04 13:34:00.063296353 -0700 shot-2014-06-22_17-10-16.jpg
2014-07-04 13:34:00.066629687 -0700 shot-2014-06-22_17-11-06.jpg
2014-06-17 19:59:38.475358571 -0700 target.txt
2014-07-05 23:53:39.097065292 -0700 test
2014-07-06 00:38:57.060521397 -0700 test.tar

Приведенный выше результат также должен помочь мне продемонстрировать, что делает весь конвейер.

  • Итак stat --printf = '} ""% z _ $ {SN} _ $ {LINENO} "\ n' выводит строки, которые выглядят так:

    }" "ГГГГ-ММ -DD ​​HH: MM: SS.NS -TZ _ $ {SN} _ $ {LINENO} "

... где YMDHMS.NS -TZ - различные компоненты strftime они представляют для ctime . Его выходной формат идентичен для % w - время рождения файла - % x - время последнего доступа - или % y - время последней модификации, и поэтому замена любого из них на % z в приведенном выше утверждении расширится до их значений. Однако, как мы уже обсуждали в комментариях, % w - время рождения файла - не является надежным атрибутом, и там, где он не поддерживается, он расширяется только до 0 .

Он делает это для каждого файла, который оболочка назначает для него в * , или для любого другого глобуса оболочки, который вы ему предоставляете - например, *. NEF только для файлов в текущем каталоге с .NEF суффикс.

  • Этот список передается в nl , в котором каждая строка нумеруется с шагом 1. Его строка -n числа ln выровнены по левому краю и не дополнены нулями. с минимальной шириной -w , равной 1, и только '' нулевую строку для -s отделяют их от содержимого строки. Он выводит:

    I} "" ГГГГ-ММ-ДД ЧЧ: ММ: SS.NS -TZ _ $ {SN} _ $ {LINENO} "

... где I - это номер каждой строки.

  • sort сортирует ввод из второго поля -k2,3 через третье - или по ГГГГ-ММ-ДД ЧЧ: ММ: SS.NS Поскольку на данный момент единственным уникальным качеством любой строки является либо I , либо дата, а I пропускается, нет необходимости вдаваться в подробности. Это также относится к вашему комментарию относительно файлов, названных по номеру, а не по дате. Я должен был выполнить сортировку до sed в первую очередь, но это не так. Мне не приходит в голову сортировать по минутам, секундам и т.п.

Моя тестовая база для этого была сгенерирована следующим образом:

for s in 9 8 7 6 5 4 3 2 1; do touch $s && sleep 1; done

Если я сортирую после sed - как я делал до этого редактирования - тогда это переименовало бы файлы так, чтобы 9 стало $ {DATE} .SHOOTNAME.9 , потому что поля YMD каждого файла являются i dentical и sort не повлияют на порядок их строк.Но с этой настройкой эта команда является sort , специфичной для наносекунды, и поэтому 9 переименовывается в $ {DATE} .SHOOTNAME.1 и наоборот для ] 1 . Спасибо, @Seul, за то, что обратил на это мое внимание.

  • sed затем удаляет первую строку, которая выглядит как <пробел> <любой символ> <любой символ>: <двоеточие> , и все символы, следующие в последовательности, которые являются ^ , а не подчеркивание _ . Итак, на данный момент строка выглядит так:

    I} "" YYYY-MM-DD _ $ {SN} _ $ {LINENO} "

... затем удаляются все тире - . И, наконец, он вставляет echo mv "$ { в ^ заголовок каждой строки, так что это выглядит так:

echo mv "${I}" "YYYYMMDD_${SN}_${LINENO}"
  • Последний вызов a sh ell с объявленной переменной окружения $ SN - здесь ее значение SHOOTNAME . POSIX указывает, что оболочка увеличивает переменную var $ LINENO для каждой строки, которую она читает, поэтому для каждой строки, которую мы передаем ей, это значение в имени файла должно расширяться на единицу больше, чем последняя. Если - как показывают ваши комментарии - по какой-то причине этого не происходит, вполне допустимой заменой будет $ ((i = i + 1)) , как впервые напечатано stat в строке 1 конвейера, и как я показал в конкретном примере ниже.

Оболочка также вызывается с ее позиционными параметрами, установленными для нашего глобуса - здесь глобальная звезда * для всех файлов в текущем каталоге. Как уже упоминалось, *. NEF в этой строке и в первой будет служить только для работы с файлами в текущем каталоге с суффиксом имени файла .NEF .

Пока его глобус совпадает с глобусом в первой строке, он будет объединять их в том же порядке, в каком они были пронумерованы nl . Таким образом, независимо от того, в какой строке он встречается , "$ {1}" будет расширяться до того же имени файла, которое мы присвоили ему в соответствии с выводом nl . Таким образом вы можете быстро, безопасно и в правильном порядке переименовывать файлы по дате.

  • Как уже упоминалось, здесь я ослабил команду с помощью echo . Но если вы запустите echo и обнаружите, что оно вам подходит, вам все-таки нужно будет удалить echo .

Примерно так:

stat --printf='}" "%z_${SN}_${LINENO}"\n' -- * | 
nl -nln -w1 -s '' |
sort -k2,3 |
sed 's| ..:[^_]*||;s|-||g;s|^|mv "${|' |
SN=SHOOTNAME sh -s -- *

Или может быть:

export SN=SHOOTNAME SUFX=.NEF
stat --printf='}" "%z_${SN}_$((i=i+1))${SUFX}"\n' -- *$SUFX | 
nl -nln -w1 -s '' |
sort -k2,3 |
sed 's| ..:[^_]*||;s|-||g;s|^|mv "${|' |
sh -s -- *$SUFX

А здесь это реализовано в функции оболочки:

_batch_date_rename () ( # a big one
    ERR= # for error reporting
    export "DIR=$1" "SUFX=$2" \ # args 1,2 must be dirname and file suffix
        "NAME=${3-${ERR:?no rename string specified}}" \ # need name string
        "TIME=${4-%y}" INT=$((${INT:-25}*3)) ${NOCONFIRM+NOCONFIRM=}
        #all above vars are exported to all points below
    _path_chk () { #run once at start - fn quits if any below test fails
        [ -d "$1" ] && [ -w "$1" ] && set -- "$1"/*"$2" && [ -e "$1" ]
    } # chks for user writable dirname and resolvable $1/*$2 glob
    _print_fmt () { #shell printf now not stat - last field zero padded
        printf 'mv "${%d}" "${DIR}/%d_${NAME}_%04d${SUFX}"\n' "$@"
    }
    _print_mv () { #prints copy of mv action before attempting 
        echo '(set -x' #uses shells debug printer to show expanded vals
        printf ': ${0+%s}\n' "$@" \
            ${NOCONFIRM-'Key "ENTER" to accept or "CTRL+C" to quit'}
        echo \) #above can be disabled by declaring NOCONFIRM at invocation
    } #by default fn batches 25 mvs at a time, displays them, and confirms
    _read_loop () { #parses piped in with IFS, batches in INTerval of 25
        argc=${1-$argc} ; ${1+shift} #total globbed files - quit point
        while IFS=' -' read nl y m d na ; do #split on -
            set -- "$@" "$nl" "$y$m$d" "$((i=i+1))" #build array until
            [ "$#" -ge "$INT" ] && break #hit interval
        done ; IFS='
';      set -- $(_print_fmt "$@") && unset IFS #finalize array in _print_fmt
        _print_mv "$@" #do the debug out
        ${NOCONFIRM+:} read < /dev/tty #if $NOCONFIRM not set confirm
        printf '%s\n' "$@" #now print the actual command
        [ $((argc>i)) -eq 1 ] || echo 'exit 0' #check if quit point     
        _read_loop #if not quit repeat
    }                                                                    
    _pipeline () { #this is mostly same - no sed though
        stat -c "$TIME" -- "$@" | nl -nln -w1 -s ' ' | sort -k2,3 | {
            _read_loop $# || echo 'exit 1' #read loop stands in for sed
        } | sh -s -- "$@" #sh still evaluates on args
    } #only two calls from main function below
    _path_chk "$1" "$2" || ${ERR:?Invalid pathname parameters specified}
    _pipeline "$DIR"/*"$SUFX" #if _path_chk do _pipeline
) #that's all folks

Она использует оболочку для некоторых вещей, которые я делал с другими утилитами. Концепция та же - составить список файлов, сортировать по-разному и сохранить порядок сортировки. Что действительно отличается от этой мысли, так это то, что он группирует операции перемещения по интервалам, отображает пользователю, что он собирается сделать, и ожидает подсказки, прежде чем продолжить. Я записал себя, используя его здесь , чтобы вы могли посмотреть, как это работает в терминальном сеансе.

4
27.01.2020, 20:16

Теги

Похожие вопросы