【问题标题】:awk - incrementing one column but keeping the rest of the column intactawk - 增加一列但保持该列的其余部分不变
【发布时间】:2014-05-20 00:03:56
【问题描述】:

我还有一个问题

我有这个数据集

1955|1;.;.;.;.;.;.; 1955|1;.;.;.;.;.;.; 1955|1;.;.;.;.;.;.; 1955|2;.;.;.;.;.;.; 1955|2;.;.;.;.;.;.; 1955|2;.;.;.;.;.;.; 1955|3;.;.;.;.;.;.; 1955|3;.;.;.;.;.;.; 1955|3;.;.;.;.;.;.; 1955|4;.;.;.;.;.;.; 1955|4;.;.;.;.;.;.; 1955|4;.;.;.;.;.;.; 1956|1;.;.;.;.;.;.; 1956|1;.;.;.;.;.;.;

下面是我想要的结果:

1955|1;.;.;.;.;.;.; 1955|2;.;.;.;.;.;.; 1955|3;.;.;.;.;.;.; 1955|4;.;.;.;.;.;.; 1955|5;.;.;.;.;.;.; 1955|6;.;.;.;.;.;.; 1955|7;.;.;.;.;.;.; 1955|8;.;.;.;.;.;.; 1955|9;.;.;.;.;.;.; 1955|10;.;.;.;.;.;.; 1955|11;.;.;.;.;.;.; 1955|12;.;.;.;.;.;.; 1956|1;.;.;.;.;.;.; 1956|2;.;.;.;.;.;.;

我正在使用这个 sn-p 的代码

for file in /cygdrive/c/work/studies/project/data/trim/"$datenow"/*v3.tsv; 
do
awk -F\| '$1!=l{c=$2}{$2=c++}{l=$1}1' OFS=\| "${file}" > "${file%.*}v4.${file##*.}"
done`

但是,它并没有按我预期的方式工作,因为它只给了我这个

1955|1 1955|2 1955|3 1955|4 1955|5 1955|6 1955|7 1955|8 1955|9 1955|10 1955|11 1955|12 1956|1 1956|2

我做错了什么?

已编辑:我已经尝试了所有可能的变化,但它没有给我我期望的结果,-F\|OFS=\;-F\;OFS=\| 但是无济于事

【问题讨论】:

  • 有点疯狂...

标签: awk


【解决方案1】:

你可以试试这个awk

awk -F"[;|]" '{$2=c++%12+1;sub(/;/,"|")}1' OFS=\; file
1955|1;.;.;.;.;.;.;
1955|2;.;.;.;.;.;.;
1955|3;.;.;.;.;.;.;
1955|4;.;.;.;.;.;.;
1955|5;.;.;.;.;.;.;
1955|6;.;.;.;.;.;.;
1955|7;.;.;.;.;.;.;
1955|8;.;.;.;.;.;.;
1955|9;.;.;.;.;.;.;
1955|10;.;.;.;.;.;.;
1955|11;.;.;.;.;.;.;
1955|12;.;.;.;.;.;.;
1956|1;.;.;.;.;.;.;
1956|2;.;.;.;.;.;.;

此版本不更改任何格式。

awk '{sub(/\|[0-9]+/,"|"c++%12+1)}1' file
1955|1;.;.;.;.;.;.;
1955|2;.;.;.;.;.;.;
1955|3;.;.;.;.;.;.;
1955|4;.;.;.;.;.;.;
1955|5;.;.;.;.;.;.;
1955|6;.;.;.;.;.;.;
1955|7;.;.;.;.;.;.;
1955|8;.;.;.;.;.;.;
1955|9;.;.;.;.;.;.;
1955|10;.;.;.;.;.;.;
1955|11;.;.;.;.;.;.;
1955|12;.;.;.;.;.;.;
1956|1;.;.;.;.;.;.;
1956|2;.;.;.;.;.;.;

它只是替换|之后的数字

【讨论】:

  • 我想保留|,Jotne。可能吗?我的文件由分号绑定,并且有一个额外的,它在我的数据集中造成了严重破坏。
  • @AndyK 修复了缺失的|
  • 你需要一个替代品...好的。让我试一试。
  • 工作就像对待。太棒了,乔特尼。
  • 如果每年没有有 12 行,这将失败。希望这就是 OP 想要的。
【解决方案2】:
$ awk 'BEGIN{FS=OFS="|"} $1!=prev{c=0} {sub(/^[^;]+/,++c,$2); prev=$1} 1' file
1955|1;.;.;.;.;.;.;
1955|2;.;.;.;.;.;.;
1955|3;.;.;.;.;.;.;
1955|4;.;.;.;.;.;.;
1955|5;.;.;.;.;.;.;
1955|6;.;.;.;.;.;.;
1955|7;.;.;.;.;.;.;
1955|8;.;.;.;.;.;.;
1955|9;.;.;.;.;.;.;
1955|10;.;.;.;.;.;.;
1955|11;.;.;.;.;.;.;
1955|12;.;.;.;.;.;.;
1956|1;.;.;.;.;.;.;
1956|2;.;.;.;.;.;.;

【讨论】:

  • 是的,这就是我所期待的……虽然我的不像这个那样惯用! :)
【解决方案3】:

一个非常相似但同样有效的答案:

awk -F"[;|]" 'OFS=";" {$2=a[$1]+++1;sub(/;/,"|"); print}' file

说明

定义两个可能的字段分隔符;和|

-F"[;|]"

定义单个输出字段分隔符;

OFS=";"

将第二个字段(在管道之后)的内容替换为由第一个字段索引的数组,每次出现时递增

awk -F"[;|]" 'OFS=";" {$2=a[$1]+++1

替换第一个FS;与 |

然后打印

打印

【讨论】:

  • 您在 awk 脚本的条件区域中有 FS=";"。该语句将为每一行输入评估一次,这是不可取的。将其从脚本中移出到 -v 分配,或将其放入 BEGIN 部分。 +++ 中的一些空格或括号将有助于显示您对该语句的操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多