使用 grep 或 sed 即时复制和修改复杂的行
complex line copying&modifying on-the-fly with grep or sed
有没有办法用 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)我们边复制边注入!我想一个解决方案(如果有的话)会非常复杂,以至于人们(包括我)看到它后会开始流血!
当然;你可以写:
sed 's/\(.*\) \(.*\) \(.*\)/ M \n M /'
$ awk -v M=2 '{print ,M,; print ,M,;}' file
Y 2 X
Y 2 Z
B 2 A
B 2 C
工作原理
-v M=2
这定义变量 M
的值为 2。
print ,M,
这将打印第二列,然后是 M
,然后是第一列。
print ,M,
这将打印第二列,然后是 M
,然后是第三列。
加长版
假设我们要处理任意数量的列,其中我们打印第一列和最后一列之间的所有列,然后打印 M,然后打印第一列,然后打印第一列和最后一列之间的所有列,然后打印 M,其次是最后一个。在这种情况下,使用:
awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,; 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,; 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
的列 在 最后一个之前。代码在其他方面是相似的。
使用 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
B 2 A
B 2 C
有没有办法用 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)我们边复制边注入!我想一个解决方案(如果有的话)会非常复杂,以至于人们(包括我)看到它后会开始流血!
当然;你可以写:
sed 's/\(.*\) \(.*\) \(.*\)/ M \n M /'
$ awk -v M=2 '{print ,M,; print ,M,;}' file
Y 2 X
Y 2 Z
B 2 A
B 2 C
工作原理
-v M=2
这定义变量
M
的值为 2。print ,M,
这将打印第二列,然后是
M
,然后是第一列。print ,M,
这将打印第二列,然后是
M
,然后是第三列。
加长版
假设我们要处理任意数量的列,其中我们打印第一列和最后一列之间的所有列,然后打印 M,然后打印第一列,然后打印第一列和最后一列之间的所有列,然后打印 M,其次是最后一个。在这种情况下,使用:
awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,; 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,; 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
的列 在 最后一个之前。代码在其他方面是相似的。
使用 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 B 2 A B 2 C