替换文件的第一列

替换文件的第一列

我有以下文件。

101; John Bauer;      811-7780831;
102; Anthony Higgins; 844-4317627; 
102; Anthony Higgins; 844-4317627;
103; Arnold Sipes;    866-4343123;
104; Donald Quinn;    877-2828732;
105; Roy Jaeger;      551-2323001;
105; Roy Jaeger;      551-2323001;
105; Roy Jaeger;      551-2323001;

我尝试使用sed自动递增值替换文件的第一列,从一开始。最终输出应该是这样的。

1; John Bauer;      811-7780831;
2; Anthony Higgins; 844-4317627; 
2; Anthony Higgins; 844-4317627;
3; Arnold Sipes;    866-4343123;
4; Donald Quinn;    877-2828732;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;

如果第一列的第一个值重复,则应该分配相同的值,因此“输出”文件上的值重复。

这可能吗?

答案1

您的模式基本上是“使第一列等于值 - 100”。AWK 适合这种情况

$ awk -F';' 'BEGIN{OFS=";"}{$1=$1-100;print }' personList.txt  
1; John Bauer;      811-7780831;
2; Anthony Higgins; 844-4317627; 
2; Anthony Higgins; 844-4317627;
3; Arnold Sipes;    866-4343123;
4; Donald Quinn;    877-2828732;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;

没有就地编辑,因此将输出重定向到新文件。

$ awk -F';' 'BEGIN{OFS=";"}{$1=$1-100;print }' personList.txt  | tee newFile.txt
1; John Bauer;      811-7780831;
2; Anthony Higgins; 844-4317627; 
2; Anthony Higgins; 844-4317627;
3; Arnold Sipes;    866-4343123;
4; Donald Quinn;    877-2828732;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;
5; Roy Jaeger;      551-2323001;

为了解决您在评论中提出的问题(如果字段#4为空,则将其设置为“不可用”),您可以使用 if 语句和正则表达式测试类数字的 4 个字符

$ awk -F';' 'BEGIN{OFS=";"}{$1=$1-100; if ($4 !~ /[[:digit:]]{4}/) $4=" N/A"  ;print }' personList.txt 

1; John Bauer;      811-7780831; 1001;
2; Anthony Higgins; 844-4317627; N/A;
2; Anthony Higgins; 844-4317627; N/A;
3; Arnold Sipes;    866-4343123; N/A;
4; Donald Quinn;    877-2828732; N/A;
5; Roy Jaeger;      551-2323001; 1267;
5; Roy Jaeger;      551-2323001; 1273;
5; Roy Jaeger;      551-2323001; 1204;

或者你可以用 if 语句做这样的事情

if ( $4 !~ /.*[0-9].*/ )

答案2

使用 Perl:

perl -F\; -lane 'BEGIN {$, = ";"} $F[0] = $F[0] - 100; print(@F)' file

要就地编辑文件:

perl -i -F\; -lane 'BEGIN {$, = ";"} $F[0] = $F[0] - 100; print(@F)' file
  • -i:指定由“<>”构造处理的文件将被就地编辑。
  • -F\;:将输入字段分隔符设置为;
  • -l: 启用自动行结束处理。它有两个不同的效果。首先,当与 -n 或 -p 一起使用时,它会自动剪切 $/(输入记录分隔符)。其次,它为 $\(输出记录分隔符)分配 octnum 的值,以便任何打印语句都会重新添加该分隔符。如果省略 octnum,则将 $\ 设置为 $/ 的当前值。
  • -a:与 -n 或 -p 一起使用时打开自动拆分模式。对 @F 数组的隐式拆分命令是 -n 或 -p 生成的隐式 while 循环中的第一件事。
  • n:导致 Perl 假设您的程序周围有以下循环,这使得它像 sed -n 或 awk 一样迭代文件名参数:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e:可用于输入一行程序。
  • BEGIN {$, = ";"} $F[0] = $F[0] - 100; print(@F):将输出字段分隔符设置为;,将第一个字段的值减少 100 并打印记录。
% cat file
101; John Bauer;      811-7780831;
102; Anthony Higgins; 844-4317627; 
102; Anthony Higgins; 844-4317627;
103; Arnold Sipes;    866-4343123;
104; Donald Quinn;    877-2828732;
105; Roy Jaeger;      551-2323001;
105; Roy Jaeger;      551-2323001;
105; Roy Jaeger;      551-2323001;
% perl -F\; -lane 'BEGIN {$, = ";"} $F[0] = $F[0] - 100; print(@F)' file
1; John Bauer;      811-7780831
2; Anthony Higgins; 844-4317627; 
2; Anthony Higgins; 844-4317627
3; Arnold Sipes;    866-4343123
4; Donald Quinn;    877-2828732
5; Roy Jaeger;      551-2323001
5; Roy Jaeger;      551-2323001
5; Roy Jaeger;      551-2323001

相关内容