我有一个包含多行/行的文件,每行包含可变数量的列:
Name1 String111 String112
Name2 String121 String122 String123
Name3 String131 String132 String133 String134
等等(没有关于哪一行有多少条目的模式)。我想将第一列中的名称添加到该行/行中每列的开头,这样我最终会得到:
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134
我们可以从简单开始,然后变得更复杂:
如何将“Test”等字符串添加到每列的开头?
如何将第 1 列中的值添加到该行中的每一列(包括第 1 列)?
如何将第 1 列中的值添加到该行中的每一列(不包括第 1 列)?
我最好的猜测:
我不知道如何调用“每一列”,也不知道如何使命令访问当前列,因此我只能将字符串或第 1 列中的值添加到其他单个列:
awk -F'\t' -vOFS='\t' '{ !$1 = "hello" $2}'
awk -F'\t' -vOFS='\t' '{ !$1 = $1 $2}'
有没有可以学习这种语法的好资源?
答案1
只需从第二个字段开始迭代所有字段,并将第一个字段连接到您已有的字段:
$ awk '{ for(i=2;i<=NF;i++){ $i = $1$i }}1' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134
最后1
是 awk 的“打印当前行”的简写。你可以这样写同样的事情:
$ awk '{ for(i=2;i<=NF;i++){ $i = $1$i }; print}' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134
上面的基本思想可以简单地扩展以匹配您的所有示例。NF
是保存字段数量的特殊 awk 变量;无论当前行中有多少个字段,它都将始终被设置为。然后,awk
允许您使用变量引用特定字段。所以如果你设置了i=5
,那么$i
就相当于$5
。然后,您可以使用将所有数字for(i=2;i<=NF;i++) { }
设置为该行上的字段数的格式来迭代所有字段。i
2
答案2
如果您的第一个字段不能包含,&
那么您需要的是:
$ awk '{gsub(/[[:space:]]+/,"&"$1)}1' file
Name1 Name1String111 Name1String112
Name2 Name2String121 Name2String122 Name2String123
Name3 Name3String131 Name3String132 Name3String133 Name3String134
答案3
在任何awk:
awk '{ OFS=" "$1; $1=$1 }1' infile
这将 OFS 设置为<SPC><first-column's-value>
然后根据 OFS 重新评估字段,$1=$1
然后打印(参见awk 习惯用法 1)。
也可以写成如下
awk '{ OFS=" "$1 } $1=$1' infile
...但是对于第一个字段所在的行来说,这将失败0
;这里我们可以使用空字符串""
来强制awk对于字符串赋值,因此 的结果$1=$1""
将始终评估为 true,因此赋值的结果将为 true,那么也会为这些行触发默认打印操作:
awk '{ OFS=" "$1 } $1=$1""' infile