shell处理数据:求最值,去重复值,筛选指定行数的值

  • A+
所属分类:linux技术
摘要

使用shell命令可以把数据文件进行像excel表格一样的操作,不仅占用内存小,而且在很多功能方面更是实力碾压excel,非常方便。

使用shell命令可以把数据文件进行像excel表格一样的操作,不仅占用内存小,而且在很多功能方面更是实力碾压excel,非常方便。

常用的命令有

(1)awk / sed 命令用于对特定行列进行操作

(2)cat / head / tail 命令用于在终端打印查看数据

(3)sort / grep 排序和筛选函数

(4)此外还常用管道和重定向命令

常用的循环结构有

(1)while型循环

while condition;do

  command  #此处写具体命令

done

(2)for循环

for (( i=0 ; i<199 ; ++i )) ; do #注意用分号隔开,双层括号,元素从0开始取,即数组索引类似python

  command  #此处写具体命令

done

下面展示几个例子:

例子1:求最值(文件第4列元素的最大值和最小值)

找出最小值的命令 "sort -n -k4 | head -n1"

找出最大值的命令 "sort -n -k4 | tail -n1"

sort选项说明:

sort -r 默认的排序方式是升序,加个-r就改成降序,需要注意-r生成的序列不支持重定向>
sort -n 默认的排序方式是字符排序,-n选项可以告诉sort要以数值来排序
sort -t 默认的间隔符为空格,-t选项后面可以设定间隔符,比如 “#”,“-”,“:” ,“_”等等
sort -k 默认的按照首列排序,-k后按照指定列数排序
sort input.txt -o output.txt  标准输入/出到文件,比重定向更好,-o常常与-r搭配使用。
sort -u 去除重复行

例子2:去重复值(从cataloge_ray数据的第四列的几百万数据中读取互不重复的199个值,并排序后写入新文件cataloge_sta_aviable.txt中)

代码一行即可

cat cataloge_ray | awk '!a[$4]++' | sort -n -k4 | awk '{print $4}' > cataloge_sta_aviable.txt
该命令可以将射线目录中的台站编号找出。(cataloge_ray共5列,$1是地震射线编号,$2是地震编号,$3到时编号,$4台站编号,$5波型;cataloge_sta_aviable.txt只有1列,将台站编号不重复,排好序,打印出来)

一个神奇的命令 awk '!a[$4]++' 它可以帮助我们在一个序列中去掉重复的值。

awk '!a[$4]++'这是一个非常经典的去重复项的awk语句,虽然短小,不过涉及到了不少知识点,下面一一解读:
<1>:”!” 即非。
<2>:a[$0],以$0为数据下标,建立数组a
<3>:a[$0]++,即给数组a赋值,a[$0]+=1
当$0的内容首次出现时,a[$0]将为空(相当于0)。
此时将先求!a[$0]的值(也是整个式子的值,即为非空 true ,将影响后续动作,执行默认的print)。
然后对a[$0]进行+1,a[$0] 加1后为1,当下次出现时a[$0]即不为空,表达式结果为非真 false,即不打印。

例子3:筛选特定行数的值(文件cataloge_sta_aviable.txt表示有效台站的序号,将这些序号的台站从stajp287文件中摘出来,并写入cataloge_sta文件)

代码如下

1 #筛选出有效的台站目录 2 line=($(awk '{print $0}' cataloge_sta_aviable.txt)) 3 for ((i=0;i<199;++i)) 4 do 5     cat stajp287 | awk 'NR=='${line[$i]}' {print $2,$1,$3}' >> cataloge_sta 6 done

该过程的难点在于:

(1)将文件内容变为数组line需要在赋值之前加“()”括号

(2)awk筛选出的内容需要用$()进行变量化

(3)逐行筛选符合要求的台站,其中NR表示行数,$1表示列数。$0表示全部

(4)在应用数组的时候需要加括号$(list[0])表示第一个元素。

(5)shell数组的第一个元素索引是0,类似python