2014-11-10 2 views
0

Там в файл с несколько строк, содержащих текст и либо даты или отметки времени:Синтаксический метка времени с помощью СЕПГ и встроенной команды

... 
string1-20141001 
string2-1414368000000 
string3-1414454400000 
... 

Я хочу, чтобы быстро преобразовать метки времени к датам, например:

$ date -d @1414368000 +"%Y%m%d" 
20141027 

и я хочу сделать это динамически с помощью sed или подобного инструмента командной строки. Для тестирования я безуспешно использовать это:

$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(date -d @\\1 +'%Y%m%d')/" 
date: invalid date '@\\1' 
something- 

но echo ИНГ, кажется, работает:

$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(echo \\1)/" 
something-1414454400 

так, что можно было бы сделать?

+0

«но эхо, похоже, работает» - нет. –

+2

у вас есть фундаментальное недоразумение, оболочка сначала оценивает аргументы перед вызовом приложения. просто «эхо», что вы хотели пройти, и вы увидите. –

+0

'bash -x' поможет вам это понять. –

ответ

0

Интересно, что здесь происходит. Некоторые указатели:

  • Всегда одинарные кавычки ваше регулярное выражение для СЭД, если это возможно, при использовании BASH (и т.д.), особенно при использовании специальных символов, таких как $. Вот почему date запускается (с -d @\\1) , прежде чем sed даже примет участие.
  • Ваш «рабочий» пример эха не является, на самом деле (я считаю): echo \\1 производит \1 (и, как указано выше, сделает это до того, как sed даже вызывается). Тогда это произойдет с действительным синтаксисом замены sed, поэтому заменит вашу группу на LHS, поэтому результат выглядит о правильном.
  • Обратите внимание, что с помощью -r вы можете использовать упрощенный/более расширенный синтаксис regex.

Трудно сказать точно, что делать без немного больше контекста, но исправить насущные проблемы, попробовать что-то вроде:

echo "something-1414454400000" | sed -re 's/-([0-9]{10,}).+/-$(date -d @\1 +"%Y%m%d")/' 

, который производит: $(date -d @1414454400) (который можно затем передать в sh)

Или для более полного решения, вы можете изменить регулярное выражение для получения команды оболочки непосредственно, и конвейер:

echo "something-1414454400000" | sed -re 's/(.*-)([0-9]{10,10}).+/echo \1$(date -d @\2 \"+%Y%M%d\")/' | sh 

..producing something-20140028

0

Вы можете сделать это в BASH:

while read -r p; do 
    if [[ "$p" =~ ^(.+-)([0-9]{10}).{3}$ ]]; then 
     echo -n "${BASH_REMATCH[1]}" 
     date -d "@${BASH_REMATCH[2]}" +"%Y%m%d" 
    else 
     echo "$p" 
    fi 
done < file 

ВЫВОД:

string1-20141001 
string2-20141026 
string3-20141027 
0

Просто попробуйте эту команду. Я проверил его. Он работает над вашими входами.

cat file | sed -E "s,(.*)-(.*),\1-`date -d @1414368000 +'%Y%m%d'`,g"