Как изменить формат даты в sed?
Скажем, я хочу преобразовать дату в метку времени в другой формат через date
команда. В консоли я бы сказал date -d@<timestamp>
но я хочу сделать это для многих полей в текстовом файле.
С использованием e
выполнить в sed
(sed (GNU sed) 4.2.2
собственно) я говорю:
$ echo 1449158360 | sed -r 's#.*([0-9]{10}).*#date -d@\1 "+%Y";#e'
2015
Это работает, приятно!
Теперь я создал фиктивный файл myfile
:
my timestamp is 1449158360 but also I wonder what date was 1359199960.
Который я хотел бы заменить на тот же, но с относительным годом временных меток:
my timestamp is 2015 but also I wonder what date was 2013.
Однако, если я попытаюсь выполнить ту же команду, что и выше, она не будет выполнена:
$ sed -r 's#([0-9]{10})#date -d@"\1" "+%Y";#e' myfile
sh: my: command not found
sh: but: command not found
Так как sed
интерпретирует первые слова как нечто для исполнения.
Очевидно, это работает, если я просто получаю эти данные и ничего больше:
$ sed -r 's#.*([0-9]{10}).*#date -d@"\1" "+%Y";#ge' myfile
2015
Поэтому мне интересно: что мне делать, чтобы позвонить date
против захваченных групп в sed
и заменить текст на него, считая, что он окружен другим текстом, который должен остаться нетронутым?
2 ответа
e
включить sed
применяется замена sh -c
для непревзойденного текста, а также видно из этой команды:
echo 'a 1449158360' | sed -r 's#([0-9]{10})#date -d@\1 "+%Y";#e'
sh: a: command not found
Так что, хотя мы сопоставляем только 1449158360
но sh -c
работает на a 1449158360
,
Из-за отсутствия регулярных выражений sed
это временное выражение может показаться сумасшедшим, но вы можете запустить его для нескольких подходящих входных данных из файла, как в вашем вопросе:
sed -r 's#(([^0-9][0-9]{0,9})*)(\b[0-9]{10}\b)(([0-9]{0,9}[^0-9])*)#printf "%s%s%s" "\1" $(date -d@\3 "+%Y") "\4";#ge' file
В основном мы совпадаем <before>10-digits<after>
в этом регулярном выражении
Выход:
my timestamp is 2015 but also I wonder what date was 2013.
Для пояснения используемого регулярного выражения я создал эту демонстрацию.
Ни в коем случае это не общее решение e
проблема режима, рассматривайте это как обходное решение на основе регулярных выражений.
Как вы сказали, с флагом e sed
получает все предложение как то, чтобы выполнить.
Поворот может быть что-то в этом роде.
+ Изменить myfile
чтобы:
echo "my timestamp is 1449158360 but also I wonder what date was 1359199960."
затем:
sed -r 's#([0-9]{10})#\`date -d@\1 "+%Y"\`#ge' myfile
Надеюсь, это поможет