需要帮助将 'while-do' 块转换为 'awk' 块以加快处理速度

Need help in converting 'while-do' block to 'awk' block for quicker processing

我需要将 csv 文件的第 7 个字段从 julian(yyddd 或 yyJJJ)转换为 yyyymmdd。我有下面的 while do 循环。我需要使用 awk 命令的相同逻辑来加快处理速度。有人可以帮忙吗?

count=0
while read -r line1; do
        col_7=$( echo $line1 | cut -d ',' -f7 | cut -c4-6)
        year1=$( echo $line1 | cut -d ',' -f7 | cut -c2-3)
        echo $col_7
        col_1=$( echo $line1 | cut -d ',' -f1,2,3,4,5,6)
        col_8=$( echo $line1 | cut -d ',' -f8 )
        date7=$(date -d "01/01/${year1} +${col_7} days -1 day" +%Y%m%d)
        echo $date7
        echo $col_1,$date7,$col_8 >> ${t2}
        count=$[count+1]
done < ${t1}

输入

xx,x,x,xxx,xxxx,xxxxx,021276,x  
xx,x,x,xxx,xxxx,xxxxx,021275,x  
xx,x,x,xxx,xxxx,xxxxx,021275,x  

输出

xx,x,x,xxx,xxxx,xxxxx,20211003,x  
xx,x,x,xxx,xxxx,xxxxx,20211002,x  
xx,x,x,xxx,xxxx,xxxxx,20211002,x  

只需消除对 cut 的所有调用就会产生奇迹;你可能不需要 awk.

count=0
while IFS=, read -r c1 c2 c3 c4 c5 c6 c7 col_8 rest; do
    col_7=${c7:3:3}
    year1=${c7:1:2}
    col_1=$c1$c2$c3$c4$c5$c6
    col_8=$c8
    date7=$(date -d "01/01/$year1 +$col_7 days - 1 day" +%Y%m%d)
    ...
    count=$((count+1))
done < "$t1"

这是 awk 的解决方案。这需要 GNU awk 的时间函数。在终端上测试过,所以它几乎是一个 one-liner 命令。

awk 'BEGIN { FS=OFS="," } { =strftime("%Y%m%d",mktime("20"substr(,2,2)" 01 01 00 00 00")+(substr(,4)*86400)-3600) } 1' filename.txt

解释:

  • FS 是字段分隔符。将其设置为“,”
  • OFS 是输出字段分隔符。将其设置为“,”
  • $7 是第 7 个字段。
  • strftime(format, timestamp) 是一个内置函数,用于根据 format 中的规范以秒为单位格式化时间戳。
  • mktime(datespec) 是将datespec 转换为秒的函数。 datespec 的格式是 YYYY MM DD HH MM SS.
  • substr($7,2,2) 是获取 two-digit 年份。
  • substr($7,4) 就是得到day。因为这些函数以秒为输入,所以需要转换为秒。
  • 86400 是 24(小时)* 60(分钟)* 60(秒)
  • 36000 是一天。 60(分钟)* 60(秒)
  • 1 用于打印输入行。不必是 1。除零以外的任何值都可以。如果您喜欢角色扮演游戏,您可能希望将其更改为 999
  • filename.txt 是您的输入文件。