用于比较单个CSV文件中两个特定行的Shell脚本

时间:2014-12-18 10:29:32

标签: shell

我正在尝试学习shell脚本。我有一个CSV文件,格式如下:

Time, value1, value2, value3
12-17 17:47:55.380,1,2,9
12-17 17:48:55.380,8,4,9
12-17 17:49:55.380,1,2,9
12-17 17:50:55.380,8,4,9

我正在寻找类似于bellow的csv输出:

0,0,0,0
1,7,2,0
1,-7,-2,0
1,7,2,0

直到现在我已经编写了代码:

First_value=ps -ef |awk "NR==1{print ;exit}" try.csv Second_value=ps -ef |awk "NR==2{print ;exit}" try.csv  echo diff = $Second_value - $First_value

但我得到的错误如下:

  

read.sh:14:read.sh:12-17:找不到。

以下是我的疑问:

  • 我无法将其置于循环中并获得输出。我想要 知道,我怎么能把结果写回同一个csv文件,但是在 特定的行和列。

1 个答案:

答案 0 :(得分:0)

以下脚本(csvdiff.sh)将比较您选择的两行,并将这些行与原始分隔字符一起输出。

#! /bin/bash

# input:   $1 - CVS file
#          $2 - line number of line to subtract from
#          $3 - line number of line to subtract

# Save separators
head -n1 $1 | sed 's/[0-9]\+/\n/g' | head -n-1 | tail -n+2 > .seps

# check for reversed compare
if [ $3 -lt $2 ]
then
    first=$3
    second=$2
    reversed=1
else
    first=$2
    second=$3
    reversed=0
fi

# get requested lines ($2 & $3) from the CVS file as supplied in $1
awk -v first=$2 -v second=$3 -F'[,: ]' 'BEGIN { OFS="\n" } 
   NR==first{ split($0,v) } 
   NR==second{ 
       split($0,w) 
       res=0 
       for (i in w) {
           $i = v[i]-w[i]
       } 
       print
    }' $1 > .vals

# handle reversed compare
if [ $reversed -eq 1 ]
then
    awk '{print $1 * -1}' .vals > .tmp
    mv .tmp .vals
fi

# paste the differences with the original seperation characters
paste -d'\0' .vals .seps | paste -sd'\0'

# remove used files
rm .vals .seps

使用示例:

$ cat file
2,2,3,4,5:10
1,2,3,4,5:12
$ chmod +x csvdiff.sh
$ bash csvdiff.sh file 1 2
1,0,0,0,0:-2
$ bash csvdiff.sh file 2 1
-1,0,0,0,0:2

请注意,此脚本将比较由多个分隔符(如冒号和逗号)分隔的字段。但是,它不会考虑像时间等语义。这意味着日期不会作为一个整体减去,而是按组件减去。