我有以下文件。
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