Sed(?) удаляет символ обратной косой черты из кавычек

Вот сценарий, который сделает это за вас, он строго использует предоставленный вами формат имени файла. Предполагая, что все файлы начинаются с даты и времени, и эта задержка составляет всего 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
0
02.04.2020, 09:03
2 ответа

Обратная косая черта является escape-символом как в двойных кавычках, так и в замене sed. Таким образом, с "\\\""sed видит \", что означает"

Попробуйте одинарные кавычки:

echo "replace FOO" | sed -e 's~FOO~test\\"test~g'

или двойной побег:

echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
1
28.04.2021, 23:19

\является специальным как для оболочки (, которая удаляет одну ), так и для 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.

0
28.04.2021, 23:19

Теги

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