Вот сценарий, который сделает это за вас, он строго использует предоставленный вами формат имени файла. Предполагая, что все файлы начинаются с даты и времени, и эта задержка составляет всего 1 час, которую необходимо исправить. Он использует время эпохи, чтобы вычесть 1 час из времени в имени файла и переименовать файлы.
Измените каталог в сценарии на ваш локальный.
looper.sh
#!/bin/bash
echo "Sending directory to the past."
for path in /path/to/directory/*.jpg; do
filename=${path##*/}
#Convert to date format
oldDate="${filename:0:4}-${filename:4:2}-${filename:6:2} ${filename:8:2}:${filename:10:2}:${filename:12:2}"
#Get the epoch date
epochDate=$(date -d "$oldDate" +%s)
#Subtract 1 hour
epochDate=$(( $epochDate - 60*60 ))
#Converting and formating the new date
newDate=$(date -d @$epochDate +%Y%m%d%H%M%S)
#New filename
newFilename=$(dirname $path)/$newDate"${filename:14}"
#Renaming the file
mv $path $newFilename
done
РЕДАКТИРОВАТЬ :Вот скрипт, сравнивающий дату рождения перед переименованием. (На всякий случай сделайте резервную копию)
#!/bin/bash
echo "Sending directory to the past."
for path in /path/to/directory/*.jpg; do
filename=${path##*/}
#Convert to date format
oldDate="${filename:0:4}-${filename:4:2}-${filename:6:2} ${filename:8:2}:${filename:10:2}:${filename:12:2}"
#Get the epoch date
epochDate=$(date -d "$oldDate" +%s)
#Birth date - Only works if your filesystem supports it.
birthDate=$(stat $path | grep 'Birth:' | sed 's/\..*//' | awk '{print $2" "$3}')
epochBirthDate=$(date -d "$birthDate" +%s)
if [ $epochDate != $epochBirthDate ]; then
#Subtract 1 hour
epochDate=$(( $epochDate - 60*60 ))
#Converting and formating the new date
newDate=$(date -d @$epochDate +%Y%m%d%H%M%S)
#New filename
newFilename=$(dirname $path)/$newDate"${filename:14}"
#Renaming the file
mv $path $newFilename
fi
done
Обратная косая черта является escape-символом как в двойных кавычках, так и в замене sed
. Таким образом, с "\\\""
sed видит \"
, что означает"
Попробуйте одинарные кавычки:
echo "replace FOO" | sed -e 's~FOO~test\\"test~g'
или двойной побег:
echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
\
является специальным как для оболочки (, которая удаляет одну ), так и для sed (, которая удаляет другую. Чтобы sed понял, что на самом деле нужно, нужно передать sed эту строку:
s~FOO~test\\\"test~g
Какой sed будет преобразован в test\"test
, что вам и нужно.
Затем оболочка должна получить либо строку в двойных кавычках, где каждый \
удвоен, и "
в кавычках \"
(, что равно 7\
):
sed "s~FOO~test\\\\\\\"test~g"
Который будет преобразован оболочкой в "s ~FOO ~test\\"test ~g", а sed будет использовать s~FOO~test\"test~g
.
Или, немного проще,используйте только одинарные кавычки'
(3\
):
sed 's~FOO~test\\\"test~g'
В комментариях вы сказали :«На самом деле я заменяю внутренний текст переменной окружения» и «К сожалению, моя переменная содержит двойные и одинарные кавычки»
Хорошо, тогда установите для вашей переменной именно то, что вы хотите, чтобы sed получал, например:
$ var='test\'\''test\"test'; echo "$var"
test\'test\"test
И, если косая черта используется только для выхода из кавычки, измените переменную с помощью этой (Предполагая bash, переносимое решение требует дополнительной работы):
$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test
Который преобразует один \
(, записанный как \\
), в три \
(, записанных как\\\\\\
).
А замена будет работать так:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
Это не общее решение для любой \
переменной.
Общее решение потребует двух проходов, чтобы удвоить все \
и затем экранировать каждую двойную кавычку:
$ var='test\'\''test\"test aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test aa\\\"bb\\\\\'cc\'
Затем изменитеvar
:
$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test aa\\\\\\\"bb\\\\\\\\\\'cc\\'
А замена будет работать так:
$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test aa\\\"bb\\\\\'cc\'
Точно исходное содержимое переменной var
.