Попробуйте перенастроить запущенные локали
sudo dpkg-reconfigure locales
Экспорт LANG
в .bashrc
повлияет только на приложения, запущенные из терминала.
В качестве альтернативы вы можете редактировать от имени root файл /etc/default/locale
, но убедитесь, что в нем присутствуют нужные вам локали, выполнив locale -a
.
В awk вы можете использовать
awk '{ cmd = "date -d@" $1; cmd | getline date; close (cmd); $1 = date; print $0; }'
Чтобы ограничиться числовыми значениями, проверьте шаблон, состоящий только из цифр:
awk '$1 ~ /^[0-9]*$/ { cmd = "date -d@" $1; cmd | getline $1; close (cmd); print $0; }'
Использование Awk:
{
"date -d @" $1 | getline $1
}
1
Результат:
Tue, Aug 21, 2018 4:47:30 PM some text
Tue, Aug 21, 2018 4:47:31 PM some more text
Tue, Aug 21, 2018 4:47:32 PM text
Если у вас есть GNU awk (, также известный как gawk
), вы можете использовать его встроенную функцию -в strftime
для преобразования времени эпохи в формат по вашему выбору:
$ TZ=UTC gawk '{$1 = strftime("%a %b %d %H:%M:%S %Z %Y", $1)} 1' file
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text
Вы также можете использовать perl с модулем POSIX
:
$ TZ=UTC perl -MPOSIX -alne '
print join " ", strftime("%a %b %d %H:%M:%S %Z %Y", localtime shift @F), @F
' file
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text
Хотя реализация GNU sed
имеет модификатор e
, позволяющий выполнять внешние команды, он работает со всем пространством шаблонов -, что делает его довольно громоздким для использования на практике.
Пакет dateutils отлично подходит для таких вещей,особенно инструмент dconv
. (При установке в системах Ubuntu команда доступна как dateutils.dconv
.)
Вот иллюстрация:
$ cat testfile.txt
1534888050 some text
1534888051 some more text
1534888052 text
$ dateutils.dconv -i '%s' -f '%a %b %d %T %Y' -S <testfile.txt
Tue Aug 21 21:47:30 2018 some text
Tue Aug 21 21:47:31 2018 some more text
Tue Aug 21 21:47:32 2018 text
$ dateutils.dconv -i '%s' -f '%F %T' -S <testfile.txt
2018-08-21 21:47:30 some text
2018-08-21 21:47:31 some more text
2018-08-21 21:47:32 text
$
Флаг -S
является ключевым; он указывает инструменту работать в «режиме sed» и включать в вывод текст даты, отличный от -.
Флаг -i
указывает формат входной даты, а флаг -f
указывает формат выходной даты.
Если sed обязателен, используйте GNU sed с:
$ sed -e 'h;s/^\([^ ]*\) \(.*\)/date -ud @\1/;e' -e 'x;s//\2/;x;G;s/\n/ /' infile.txt
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text
В противном случае снаряд мог сделать:
$ TZ=UTC0 bash -c 'while read a b; do printf '\''%(%c)T %s\n'\'' "$a" "$b"; done <infile'
Tue 21 Aug 2018 09:47:30 PM UTC some text
Tue 21 Aug 2018 09:47:31 PM UTC some more text
Tue 21 Aug 2018 09:47:32 PM UTC text
Или, что еще лучше, используйте awk:
$ awk '{c="date -ud @" $1;c|getline $1;close(c)}1' infile.txt
Tue Aug 21 21:47:30 UTC 2018 some text
Tue Aug 21 21:47:31 UTC 2018 some more text
Tue Aug 21 21:47:32 UTC 2018 text
Что вам нужно понять, так это то, что GNU sed
заменяет все пространство шаблонов результатом вычисления команды в RHS s///e
. Поэтому, чтобы приспособиться к такому поведению, мы используем комбинацию команд echo + date
, как показано:
sed -e 's/^\([1-9][0-9]*\)\(.*\)/echo "`date -d@\"\1\"`\2"/e' input-file.txt
А с Perl
все просто в том, что то, что сопоставляется в левой части, заменяется только в правой части, как можно было бы интуитивно ожидать также:
perl -pe 's/(\d+)/qx(date -d@"$1") =~ s|\n||r/e' input-file.txt