Используйте команду date в аргументах awk - PullRequest
0 голосов
/ 03 октября 2018

У меня есть файл, который выглядит следующим образом

server1-adm.test.com,/var,dir,29987,2007-12-03 15:52:43,root,root
server2.fs.com,/DATA_File.out,file,299076487,2008-10-15 05:12:23,user1,group1
server3-prd.mod.com,/opt,dir,29987,2009-05-03 00:13:23,user1,group1
server4,/var/tmp/xxz.zip,file,400,2007-12-03 15:52:43,root,root
server1-adm.test.com,/usr,dir,34299876,2006-12-03 16:52:43,root,root
server3-prd.mod.com,/local/home,dir,400,2009-05-03 12:13:23,user2,group1

5-й столбец - это значение date + time, которое я хочу изменить.Я пытался использовать несколько операторов awk вместе, но это выглядело слишком запутанно, склонно к ошибкам.Вместо использования нескольких операторов для преобразования формата даты, как я могу использовать системную команду date в awk для преобразования в результаты ниже.

server1-adm.test.com,/var,dir,29987,2007-12-03 03:52:43 PM,root,root
server2.fs.com,/DATA_File.out,file,299076487,2008-10-15 05:12:23 AM,user1,group1
server3-prd.mod.com,/opt,dir,29987,2009-05-03 00:13:23 AM,user1,group1
server4,/var/tmp/xxz.zip,file,400,2007-12-03 03:52:43 PM,root,root
server1-adm.test.com,/usr,dir,34299876,2006-12-03 04:52:43 PM,root,root
server3-prd.mod.com,/local/home,dir,400,2009-05-03 12:13:23 PM,user2,group1

Что-то в строках date -d "2007-12-03 15:52:43" +%Y/%m/%d:%H%M%S.Я не знаю, как мы можем получить AM / PM в команде date.

У меня уже есть несколько операторов awk, выполняющихся вместе как часть скрипта для выполнения другой модификации текста в том же входящем файле, поэтому яхотел бы использовать оператор awk + date для этого.

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Вы можете просто использовать команду date непосредственно для переменной $5, как показано ниже.Будьте осторожны с цитированием команды.Здесь мы формируем командную строку cmd из $5 с необходимыми флагами, используя %p, чтобы вывести соответствующие AM или PM в зависимости от времени дня.

awk -v FS=, -v OFS=, '{cmd = "date -d \""$5"\" \"+%Y-%m-%d %I:%M:%S %p\""}{ cmd|getline D; close(cmd); $5=D}1' file

Важнейшая часть в close(cmd) заявлении.Это заставляет awk выполнять cmd каждый раз, поэтому дата будет действительной каждый раз.Также см. Использование getline в переменной из трубы

0 голосов
/ 03 октября 2018

Если вы можете использовать GNU awk, он предоставляет некоторые функции времени, которые заставят вашу программу работать намного быстрее, чем вызов вашей оболочки + date для каждой строки вашего CSV-файла:

awk 'BEGIN { FS = OFS = "," } { gsub("[-:]", " ", $5); $5 = strftime("%F %r", mktime($5)) } 1'

Расширенная форма:

awk '
    BEGIN { FS = OFS = "," }

    {
        gsub("[-:]", " ", $5)
        $5 = strftime("%F %r", mktime($5))
    }

    1
'

Если вы действительно хотите использовать внешнюю команду date, как вы указали в своем вопросе, тогда используйте GNU awk совместные процессы, чтобы только один date команда запускается и повторно используется в каждой строке:

awk 'BEGIN { FS = OFS = ","; cmd = "stdbuf -oL date -f - +%F\" \"%r" } { print $5 |& cmd; cmd |& getline $5 } 1'

Расширенная форма:

awk '
    BEGIN {
        FS = OFS = ","
        cmd = "stdbuf -oL date -f - +%F\" \"%r"
    }

    {
        print $5 |& cmd
        cmd |& getline $5
    }

    1
'

Но вам действительно следует пойти с первым решением.

0 голосов
/ 03 октября 2018

Не могли бы вы попробовать следующее.

awk -F'[ ,]' '{split($6,array,":");$6=array[1]>12?sprintf("%02d",array[1]-12)":"array[2]":"array[3]" PM":(array[1]==12?$6 " PM":$6 " AM")} 1'  Input_file

Объяснение: Добавление объяснения здесь для приведенного выше кода.

awk -F'[ ,]' '                                                         ##Making field separator as space and comma for all the lines of Input_file.
{
  split($6,array,":")                                                  ##using split function to split 6th field of current line by making : as field sep for it.
  $6=array[1]>12?sprintf("%02d",array[1]-12)":"array[2]":"array[3]" PM" :$6 " AM" ##re-creating $6 value by checking condition if its 1st value array value which is time is greater than 12 than subtracting its value with 12 here and adding PM and AM according to it too.
}
1                                                                      ##Mentioning 1 will print the edited/non-edited value of line.
' Input_file                                                       ##Mentioning Input_file name here.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...