使用bash,sed和awk增加文件中列的值

时间:2014-03-21 13:28:38

标签: bash sed awk

请在下面找到我的一个文件的摘录。

1991;1;-7;-3;-9;-4;-7
1991;1;-7;-3;-9;-4;-7
1991;1;-7;-3;-9;-4;-7
1991;2;-14;-11;-14;-4;-14
1991;2;-14;-11;-14;-4;-14
1991;2;-14;-11;-14;-4;-14
1991;3;-7;-3;-15;5;-7
1991;3;-7;-3;-15;5;-7
1991;3;-7;-3;-15;5;-7
1991;4;-15;-9;-21;1;-16
1991;4;-15;-9;-21;1;-16
1991;4;-15;-9;-21;1;-16
1992;1;-12;-6;-19;-2;-12
1992;1;-12;-6;-19;-2;-12
1992;1;-12;-6;-19;-2;-12
1992;2;-16;-7;-22;-12;-15
1992;2;-16;-7;-22;-12;-15
1992;2;-16;-7;-22;-12;-15
1992;3;-22;-15;-25;-16;-24
1992;3;-22;-15;-25;-16;-24

我尝试通过sed或/和awk在第二列上为第二行添加+ 1,只要第一列中的年份保持不变。

结果将如下:

1991;1;-7;-3;-9;-4;-7
1991;2;-7;-3;-9;-4;-7
1991;3;-7;-3;-9;-4;-7
1991;4;-14;-11;-14;-4;-14
1991;5;-14;-11;-14;-4;-14
1991;6;-14;-11;-14;-4;-14
1991;7;-7;-3;-15;5;-7
1991;8;-7;-3;-15;5;-7
1991;9;-7;-3;-15;5;-7
1991;10;-15;-9;-21;1;-16
1991;11;-15;-9;-21;1;-16
1991;12;-15;-9;-21;1;-16
1992;1;-12;-6;-19;-2;-12
1992;2;-12;-6;-19;-2;-12
1992;3;-12;-6;-19;-2;-12
1992;4;-16;-7;-22;-12;-15
1992;5;-16;-7;-22;-12;-15
1992;6;-16;-7;-22;-12;-15
1992;7;-22;-15;-25;-16;-24
1992;8;-22;-15;-25;-16;-24

我已经在stackflow上看到了无数的例子,但没有什么可以让我接近解决方案。

我欢迎任何建议。

最佳,

4 个答案:

答案 0 :(得分:7)

如果您总是希望第2列在第1列中首次出现的行中为1,则:

awk -F\; '$1!=l{c=0}{$2=++c}{l=$1}1' OFS=\; input

如果你想维护第2栏中的内容:

awk -F\; '$1!=l{c=$2}{$2=c++}{l=$1}1' OFS=\; input

答案 1 :(得分:4)

这可以用awk更简洁地完成,但纯粹的bash工作正常:

last_year=
counter_val=
while IFS=';' read -r year old_counter rest; do
  if [[ $year = "$last_year" ]]; then
    (( ++counter_val ))
  else
    counter_val=1
    last_year=$year
  fi
  printf -v result '%s;' "$year" "$counter_val" "$rest"
  printf '%s\n' "${result%;}"
done <input.txt >output.txt

答案 2 :(得分:1)

您只想增加第二列,而不是添加第二列?无论第二列是什么,您是否希望第二列从一开始?

awk -F\; '{
    if ( NR == 1 ) {
        year = $0
    }
    if ( year == $0 ) {
        for (count = 1; count < NF; count++) {
            if ( count == 2) {
                printf NR ";";
            }
            else {
                printf $count ";";
            }
        }
        print "";
    }
    else {
        print 
    }
}' test.txt

Awk是一个自然的程序,因为它在假设循环时运行。另外,它的数学运算比普通的shell更自然。

NR表示记录数NF表示字段数。字段由我的-F\;参数分隔,记录是我文件中的行号。该计划的其余部分非常明显。

答案 3 :(得分:1)

使用awk,将FS(字段分隔符)和OFS(输出字段分隔符)设置为&#39 ;;&#39;和 对于每个新年记录,将val计数器设置为起始列2的值。该年度每行增加val

awk -F';' 'BEGIN{OFS=";";y=0} 
 { if (y!=$1) 
      {y=$1;val=$2;print} 
   else 
      {val++;print $1,val,$3,$4,$5,$6,$7}}' data_file