У меня есть строка

STR="<trkpt lat="53.4829787887" lon="-113.518349362"><ele>682.0</ele><time>2020-01-09T01:00:01Z</time><speed>20.0</speed></trkpt>"

И я пытаюсь заменить время временем + 1 секунда.

Для этого у меня есть:

echo $STR | sed -e 's/<time>\(.*\)<\/time>/<time>'$(TZ=UTC date "+%Y-%m-%dT%H:%M:%SZ" -d "\1 + 1 seconds")'<\/time>/g'

Однако я продолжаю получать ошибку

date: invalid date ‘\\1 + 1 seconds’

Почему \1 интерполируется как \\1 в подоболочке $()?

Может кто-нибудь, пожалуйста, помогите, где я ошибаюсь, и помогите понять, что здесь происходит.

Использование gnused 4.4.

0
abhishek nair 9 Янв 2020 в 05:17
Sed не предназначен для анализа XML или HTML.
 – 
Gilles Quenot
9 Янв 2020 в 03:54
2
Оболочка оценивает $(TZ=UTC date "+%Y-%m-%dT%H:%M:%SZ" -d "\1 + 1 seconds") и затем вызывает sed с результатом в качестве строки замены, я думаю
 – 
steeldriver
9 Янв 2020 в 03:56
@ЖильКуэно. Теоретически обратные ссылки должны работать так же, как и переменные, за исключением того, что они являются последовательными заполнителями для того, что захвачено между выражением \(\).
 – 
abhishek nair
9 Янв 2020 в 04:39
1
echo $STR | sed -r "s|<time>(.*)</time>|<time>$(date -d \1' + 1 seconds' '+%Y-%m-%dT%H:%M:%SZ')</time>|g"
 – 
ipatev_nn
9 Янв 2020 в 10:55

1 ответ

Что бы я сделал, используя правильный синтаксический анализатор XML и (не используйте sed для этой задачи):

Входной файл

$ cat file.xml
<trkpt lat="53.4829787887" lon="-113.518349362">
  <ele>682.0</ele>
  <time>2020-01-09T01:00:01Z</time>
  <speed>20.0</speed>
</trkpt>

Вы можете редактировать на лету с помощью xmlstarlet ed -L -u ...

Команды

d=$(xmlstarlet sel -t -v '/trkpt/time/text()' file.xml)
xmlstarlet ed -u '/trkpt/time/text()' -v $(
    TZ=UTC date "+%Y-%m-%dT%H:%M:%SZ" -d "$d + 1 seconds"
) file.xml

Выход

<?xml version="1.0"?>
<trkpt lat="53.4829787887" lon="-113.518349362">
  <ele>682.0</ele>
  <time>2020-01-09T01:00:02Z</time>
  <speed>20.0</speed>
</trkpt>
2
Gilles Quenot 9 Янв 2020 в 04:04
Спасибо @Жиль Кено! Мне нравится использование xmlstarlet и решает проблему! Однако я не могу понять, почему \1 интерполируется как \\1 в подоболочке.
 – 
abhishek nair
9 Янв 2020 в 04:30
Я чувствую, что вы тратите время на конкретный артефакт, когда вы можете узнать что-то новое и, возможно, более интересное :) Мои 2 цента.
 – 
Gilles Quenot
9 Янв 2020 в 04:52
Просто пытаюсь лучше понять sed. :)
 – 
abhishek nair
9 Янв 2020 в 05:21
Это не имеет ничего общего с sed: см. комментарий @steeldriver.
 – 
NickD
9 Янв 2020 в 06:23
...или, другими словами: попробуйте выполнить команду TZ=UTC date "+%Y-%m-%dT%H:%M:%SZ" -d "\1 + 1 seconds" в вашей оболочке.
 – 
NickD
9 Янв 2020 в 06:26