使用大型文件在bash中解析文件和日期操作

时间:2019-03-29 13:37:54

标签: bash date awk getline

我正在寻找一种更好的方法来将日期格式转换为所需的格式。我确实做到了,但是我不得不多次处理文件,因为我无法一次通过date来完成文件。

我使用的格式:
Wed Jan 30 08:00:00 2019 : misc data

我想要的格式:
30/01/2019 08:00:00 : misc data

但是,如果日期格式为以下格式,我只能获取date来处理日期信息:
30-Jan-2019 08:00:00 : misc data

(注意:misc data是一个包含许多笨拙字符的长字符串)

要实现我要使用的功能:

awk '{("date --date="$3"-"$2"-"$5"\\ "$4" +%F") | getline $1;$2="";$3="";$4;$5=""} 1' oldfile | tr -s ' ' > newfile

这是创建一种我可以使用的格式,将其解析为字段$ 1,清除字段2、3和5,将其打印出来(保留字段4中的时间,以及其他数据)并去除多余的空格保留在空白字段旁边,并将其保存到新文件中。然后,我必须将包括分隔符的格式(因为date不喜欢/(如果使用命名月份))转换为新格式,并且整个过程变得太复杂了。

然后我在其上运行另一个awk,交换周围的字段和分隔符。

我敢肯定,这可以简化,但是现在开始让我感到困惑。

我确实意识到我应该使用format的输出date,但是由于涉及到斜杠,所以只要我包含单引号或双引号,或尝试对它们进行转义,我就会发现任何涉及多个格式元素的操作都会失败。

更糟糕的是,当我处理一组有限的数据(通常是受headtail限制的示例时,所有这些都可以工作,但是原始文件的长度约为20,000个条目,并且失败FNR=1043处打开的文件过多。这只是一个打开的文件并保存了一个文件。我认为这是使用getline的结果。有没有办法不使用它? ?

2 个答案:

答案 0 :(得分:3)

您无需致电date即可随机播放文本:

$ echo 'Wed Jan 30 08:00:00 2019 : misc data' |
awk '{
    mthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)+2)/3
    date = sprintf("%02d/%02d/%04d %s", $3, mthNr, $5, $4)
    sub(/^([^ ]+ +){5}/,"")
    print date, $0
}'
30/01/2019 08:00:00 : misc data

btw出现的too many open files错误是因为您没有在每次调用getline之后关闭管道。有关何时以及如何可靠使用getline的信息,请参见http://awk.freeshell.org/AllAboutGetline

答案 1 :(得分:0)

另一个awk

$ echo 'Wed Jan 30 08:00:00 2019 : misc data' | awk -F: -v OFS=: ' { t=$NF;NF--; 
    cmd="date -d\047" $0 "\047 \047+%d/%m/%Y %T\047"; if ( (cmd | getline line) > 0 ) 
    close(cmd); print line,t}'
30/01/2019 08:00:00: misc data
$