简体   繁体   English

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

[英]increment values in column within file with bash, sed and awk

Please find below an excerpt from one of my file. 请在下面找到我文件之一的摘录。

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

I'm trying through sed or/and awk to add + 1 on the second column for the second row for the second row as long as the year in the first column remains the same. 我正在尝试通过sed或/和awk在第二行的第二列上为第二行添加+1,只要第一列中的年份保持不变即可。

The results would be the following: 结果如下:

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

I've seen countless examples on stackflow but nothing that can lead me close to a solution. 我在堆栈流上看到了无数的示例,但是没有什么可以使我接近解决方案。

I welcome any suggestions. 我欢迎任何建议。

Best, 最好,

If you always want the 2nd column to be 1 for the line in which the year first appears in column 1, then: 如果您始终希望第一年出现在第1列的行的第2列为1,则:

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

If you want to maintain whatever was in column 2: 如果您想维护第2列中的内容:

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

This could be done more tersely with awk, but pure bash works fine: 使用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

You simply want to increment your second column, and not add one to it? 您只是想增加第二列,而不是增加第二列? Do you want the second column to go from one onward no matter what the second column is? 无论第二列是什么,您是否都想从第二列开始?

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 is a natural program to use because it operates in assuming a loop. Awk是自然使用的程序,因为它在假设循环中运行。 Plus, it's math is more natural than plain shell. 另外,它的数学运算比纯壳运算自然。

The NR means Number of Records and NF means Number of fields . NR表示记录数, NF表示字段数 A field is separated by my -F\\; 字段由我的-F\\;分隔-F\\; parameter, and the record is the line number in my file. 参数,而记录是我文件中的行号。 The rest of the program is pretty obvious. 该程序的其余部分非常明显。

Using awk, set the FS (field separator) and OFS (output field separator) to ';' 使用awk,将FS (字段分隔符)和OFS (输出字段分隔符)设置为“;” and for each new year record set the val counter to the start column 2 value. 并将每个新年记录的val计数器设置为第2列的开始值。 Increment val for each line with that year. 增量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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM