awk处理9G级别文件

如何处理9G级别文件,直接导入性价比不高,那就按照流处理器进行

awk处理单文件级别

awk轻松解决大文件级别的遍历问题,并提取需要的字段。

  awk -F"," '/_028\./{print $1,",",$3,",",$4;}' js_df_20220309.csv > 20220309_28.csv

## /_028\./ 的28表示第28台风电机组,$1,$3,$4 分别为时间、物理量、值
## /_029\./ 的29表示第29台风电机组,$1,$3,$4 分别为时间、物理量、值

那如何提取所有机组信息,每个机组都变换一下 那如何解决一个文件夹内的所有文件问题? 每个文件名字都包含年月日信息,另外awk的模式不能包含变量,那么只能说awk解析的时候,我们必须把字面值提供给awk了

第一步:尝试解析2级循环,循环91台机组

seq等宽输出

seq等宽输出可以采用-w option,这样输出就是相同长度,可以提供模式匹配需要

seq -w 001 091

我的测试代码:

for day in `ls *.csv`;do day1=${day:6};realDay=${day1:0:-4};echo $realDay; for turbine in `seq -w 003 1 91`; do turbinePattern="_$turbine\."; outputFilename=$realDay"_"$turbine".csv";echo $turbinePattern,$turbine,$outputFilename;done;done

错误的命令

下面命令无法获得你想要单台机组信息,因为$turbinePattern根本就不会解析为`_028.`的 模式,因为//不能解析变量,所以解决办法是我们提供斜杠号之间变量值

但是perl的模式匹配中确实可以,参考perl拆分大文件 可见perl正则的强大。

单行执行程序:

for day in `ls *.csv`;do day1=${day:6};realDay=${day1:0:-4};echo $realDay; for turbine in `seq -w 003 1 91`; do turbinePattern="_$turbine\."; outputFilename=$realDay"_"$turbine".csv";awk -F"," '/$turbinePattern/{print}' echo $turbinePattern,$turbine,$outputFilename;done;done

bash包装awk可执行语句

我们可以包装awk命令,最后交给bash执行(很重要的bash命令)

我的awk命令封装测试代码(重大突破)

注意双引号要用反斜杠去引用!(去引用是一个基本的业务操作)

86151@DESKTOP-O9MPS4C /cygdrive/f/js_df/ceshi
$ echo "awk -F\",\" '{print $2}' 20200109_28.csv >heklo.csv"|bash

86151@DESKTOP-O9MPS4C /cygdrive/f/js_df
$  d1="_001\.";cmd="awk -F\",\" '/$d1/{print \$1,\",\",\$3,\",\",\$4;}' js_df_20220109.csv > 20220009_001.csv" ;echo $cmd|bash

最终的成品

  1. 遍历文件
  2. 文件名字截取重要部分
  3. 生成所有机组的匹配模式
  4. 生成awk命令字符串,包装机组模式变量
  5. bash执行
for day in `ls *.csv`;do day1=${day:6};realDay=${day1:0:-4};echo $realDay; for turbine in `seq -w 001 091`; do turbinePattern="_$turbine\."; outputFilename=output/$realDay"_"$turbine".csv";cmd="awk -F\",\" '/$turbinePattern/{print \$1,\",\",\$3,\",\",\$4;}' $day >$outputFilename";echo $cmd|bash;done;done

sed存在的意义

awk于1977年出生,现在46岁了,sed比awk大2-3岁。

  • 快速读取前面几行

  • 最后一行或者中间行快速插入相关信息

  • 最流行的替换功能`sed ’s/hell//’ file`, 如果加入"-i"选项则表示直接在文件中修改;

    还可以指定行进行修改,比如"sed ‘3,6s/my/yours/g’ file"

    每行匹配可能有多个,还可以指定每行第几个匹配进行修改,比如第二个匹配修改"sed ‘3,6s/my/yours/2’ file" 比如第三个匹配修改"sed ‘3,6s/my/yours/3’ file"

    还比如第三个以后的所有匹配都修改,加入g即可,“sed ‘3,6s/my/yours/3g’ file”

    还比如匹配位置后面连续3行, “$ sed ‘dog,+3s/^/# /g’ pets.txt” +3代表匹配后的连续3行

    命令还可以打包 # 对3行到第6行,匹配_This_成功后,再匹配_fish_,成功后执行d命令 $ sed ‘3,6 {/This/{/fish/d}}’ pets.txt

    参考cool sed

    sed ’s/my/[&]/g’ my.txt ,&代表匹配的my

    sed ‘N;s/\n/,/’ pets.txt N命令快速合并前后两行(1,2行合并为1行,3,4行合并为1行)

可以学习一下陈浩的酷壳博客 sed很关键的几个概念是地址(行或者模式指定),!是否执行,cmd命令流(增删查找)

10q,代表读到第十行则quit!

$ sed '10q' js_df_20220109.csv
2022-01-09 00:00:01,1641657601032,JS_DF_1_008.1.DD,0.0,,tenant_system,,1641657600,1
2022-01-09 00:00:01,1641657601032,JS_DF_1_008.1.DE,34.7,,tenant_system,,1641657600,1
  • 最后一行或者中间行快速插入相关信息
[root@www ~]# sed -i '$a # This is a test' regular_express.txt
[root@www ~]# cat regular_express.txt
runoob!
google!
taobao!
facebook!
zhihu-
weibo-
# This is a test
由於 $ 代表的是最后一行,而 a 的动作是新增,因此该文件最后新增 # This is a test!

sed 的 -i 选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个 100 万行的文件,你要在第 100 行加某些文字,此时使用 vim 可能会疯掉!因为文件太大了!那怎办?就利用 sed 啊!透过 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修订

awk获取机组台数信息

awk字符串分割(多个分割模式) uniq去重(uniq -c 加上统计功能)

awk -F"," '{split($3,a,"[_.]");print a[4];}' /tmp/test.csv|uniq

当然也可以使用 substr

awk -F ',' '{print substr($3,6)}'  #  --->  表示是从第3个字段里的第6个字符开始,一直到设定的分隔符","结束.
substr($3,10,8)  #--->  表示是从第3个字段里的第10个字符开始,截取8个字符结束.
substr($3,6)     #--->  表示是从第3个字段里的第6个字符开始,一直到结尾
Related
叶昭良
叶昭良
Engineer of offshore wind turbine technique research

My research interests include distributed energy, wind turbine power generation technique , Computational fluid dynamic and programmable matter.