2016-10-20 2 views
1

Я пытаюсь работать над скриптом, где он имеет столбец, объединенный с датой и некоторой строкой. Я хочу подстроить дату и сравнить с сегодняшней датой. Если он старше, чем сегодня, я хочу заменить сегодняшнюю дату. Вот пример.Команда Unix для замены старой даты с текущей датой динамически

cat test.txt 
aaaa    RR 242  644126    20161030O00001.0000 
bbbb    RR 242  644126    20161225O00001.0000 
aaaa    RR 242  644126    20161012O00001.0000 
aaaa    RR 242  644126    20170129O00001.0000 
aaaa    RR 242  644126    20170326O00001.0000 
aaaa    RR 242  644126    20170430O00001.0000 
aaaa    RR 242  644126    20161015O00001.0000 

Я хочу, чтобы результат был следующим, изменив отметку даты для colum5 - ряд 3 и 7. Пожалуйста, помогите. Я ищу одну команду, чтобы она работала, если это возможно.

aaaa    RR 242  644126    20161030O00001.0000 
bbbb    RR 242  644126    20161225O00001.0000 
aaaa    RR 242  644126    20161020000001.0000 
aaaa    RR 242  644126    20170129O00001.0000 
aaaa    RR 242  644126    20170326O00001.0000 
aaaa    RR 242  644126    20170430O00001.0000 
aaaa    RR 242  644126    20161020000001.0000 
+1

Итак, учитывая, что сегодняшняя дата - 2016-10-20, если дата данных даты соответствует дате старше 2016-10-20, вы хотите заменить дату на 2016-10-20 , но если это будущая дата в 2016 году или в 2017 году или за ее пределами, оставьте ее в покое? И сроки могут быть с 2015 года или раньше? Является ли буква после поля даты всегда «O», как в вашем примере? –

+0

Я попытался спасти форматирование и удалил пустые строки между каждой строкой в ​​примерах. Я полагаю, что звездочки также не являются частью данных; не могли бы вы рассмотреть и [изменить] ваш вопрос, чтобы уточнить? – tripleee

+0

Разделение даты с другими данными может показаться способом продвижения вашего собственного здравомыслия и упрощения дальнейшей последующей обработки. – tripleee

ответ

0

Если perl в порядке ...Примечание: 2016-10-21 уже в моей части мира;)


Чтобы получить текущую дату, используя Time::Piece модуль:

$ perl -MTime::Piece -le '$d = localtime->ymd(""); print $d' 
20161021 


Пример ввода:

$ cat ip.txt 
aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161225O00001.0000 
aaaa RR 242 644126 20161012O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161015O00001.0000 

$ perl -MTime::Piece -pe 'BEGIN{$d=localtime->ymd("")} s/.* \K\d+/$& < $d ? $d : $&/e' ip.txt 
aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161225O00001.0000 
aaaa RR 242 644126 20161021O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161021O00001.0000 
  • BEGIN{$d=localtime->ymd("")} сохранить текущую дату в $d переменной, сделать это только при запуске сценария даты
  • s/.* \K\d+/$& < $d ? $d : $&/e экстракт должен быть заменен, сравниваться $d и заменить $d, если извлеченный дата ранее $d

    • .* \K соответствуют последнему пробелу в строке, используя \K, совпадающий текст до этой точки отбрасывается

    • $& содержит найденную строку из \d+

    • e флага позволяет использовать код $& < $d ? $d : $& вместо строки в замене секции


Используя date команды вместо Time::Piece модуля:

perl -pe 'BEGIN{chomp($d=`date +%Y%m%d`)} s/.* \K\d+/$& < $d ? $d : $&/e' ip.txt 


Дальнейшее чтение:

2

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

awk -v refdate="$(date +%Y%m%d)" '{ if ($5 < refdate) $5 = refdate substr($5, 9); print}' 

Данный файл данных и тока дата 2016-10-20:

aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161225O00001.0000 
aaaa RR 242 644126 20161012O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161015O00001.0000 

Выход:

aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161225O00001.0000 
aaaa RR 242 644126 20161020O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161020O00001.0000 
+0

Я использую это в solaris. Похоже, синтаксис не принимается. – Kate

+0

awk -v refdate = "$ (date +% Y% m% d)" '{if ($ 5 Kate

+0

Если вы находитесь в Solaris, проблема может заключаться в том, что '$ (...)' все еще не распознается оболочкой, которую вы Использование ('/ bin/sh' в Solaris - это несколько десятилетий за раз). Возможно, вам придется использовать: '' 'awk -v refdate =' date +% Y% m% d' '{...}' test.txt'''. Если это не устранит проблему, вам нужно посмотреть справочную страницу Solaris Awk и узнать, распознан ли 'substr'. Я думаю, что back-ticks вместо '$ (...)', вероятно, решит проблему, но есть способы отладки вещей, если этого недостаточно. –

0

В Gnu AWK (см последний комментарий в пояснениях):

$ awk -v a="$(date +%Y%m%d)" '(b=substr($5,1,8)) && sub(/^.{8}/,(b<a?a:b),$5)' file 
aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161225O00001.0000 
aaaa RR 242 644126 20161021O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161021O00001.0000 

Разъяснение:

awk -v a="$(date +%Y%m%d)" # set the date to a var 
'       # ' 
(b = substr($5,1,8)) && # read first 8 chars of 5th field to b var 
sub(/^.{8}/, (b<a?a:b), $5) # replace 8 first chars with a if b is less than a 
          # to make it compatible with other awks, change 
          # /^.{8}/ to /^......../ 
' file 
+0

Он не работает в Solaris. – Kate

+0

На Gnu awk? Вы пытались изменить комментарии (непроверенные в Solaris)? –

+0

Я не уверен, как изменить эту часть sub (/ ^. {8} /, (b Kate

0

Я понял, наконец! Спасибо Джеймсу, Джонатану и другим.

Вот моя команда в solaris.

$cat test.txt 
aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161012O00001.0000 
aaaa RR 242 644126 20161013O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161014O00001.0000 

$ /usr/xpg4/bin/awk -v a=`date +%Y%m%d` '(b=substr($5,1,8)) && gsub(/^.{8}/,(b<a?a:b),$5)' test.txt  
aaaa RR 242 644126 20161030O00001.0000 
bbbb RR 242 644126 20161022O00001.0000 
aaaa RR 242 644126 20161022O00001.0000 
aaaa RR 242 644126 20170129O00001.0000 
aaaa RR 242 644126 20170326O00001.0000 
aaaa RR 242 644126 20170430O00001.0000 
aaaa RR 242 644126 20161022O00001.0000 
+0

/usr/xpg4/bin/awk -va = 'date +% Y% m% d' '(b = substr ($ 5,1,8)) && gsub (/ ^. {8} /, (b Kate

Смежные вопросы