>有没有办法使用 grep 或 sed 执行以下操作:读取文件的每一行,复制两次并修改每个副本:
原行:
X Y Z
A B C
新行:
Y M X
Y M Z
B M A
B M C
其中 X、Y、Z、M 都是整数,M 是我们在复制时注入的固定整数(即 2)!我想一个解决方案(如果有的话)会非常复杂,以至于人们(包括我)在看到它后会开始流血!
$ awk -v M=2 '{print $2,M,$1; print $2,M,$3;}' file
Y 2 X
Y 2 Z
B 2 A
B 2 C
工作原理
-v M=2
这将变量
M
定义为具有值 2。print $2,M,$1
这将打印第二列,后跟
M
,后跟第一列。print $2,M,$3
这将打印第二列,后跟
M
,后跟第三列。
扩展版本
假设我们要处理任意数量的列,其中我们打印第一列和最后一列之间的所有列,后跟 M,然后是第一列,然后打印第一列和最后一列之间的所有列,后跟 M,后跟最后一列。 在这种情况下,请使用:
awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,$1; for (i=2;i<NF;i++)printf "%s ",$i; print M,$NF;}' file
例如,请考虑以下输入文件:
$ cat file2
X Y1 Y2 Z
A B1 B2 C
以上产生:
$ awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,$1; for (i=2;i<NF;i++)printf "%s ",$i; print M,$NF;}' file2
Y1 Y2 2 X
Y1 Y2 2 Z
B1 B2 2 A
B1 B2 2 C
对代码的关键更改是添加了以下命令:
for (i=2;i<NF;i++)printf "%s "
此命令打印i=2
中的所有列,这是第一个到i=NF-1
之后的列,最后一个列之前的列。 代码在其他方面是相似的。
当然;你可以写:
sed 's/(.*) (.*) (.*)/2 M 1n2 M 3/'
使用 bash 内置命令:
m=2; while read a b c; do echo "$b $m $a"; echo "$b $m $c"; done < file
输出:
Y 2 X Y 2 Z 乙 2 安培 B 2 C