我想用现有文件中的选择列创建一个新文件。我想选择基于“ X”的行,然后按原样打印列1、2、4和5。然后,我想基于定界符“:”将第10列拆分为最后一列(50),并仅提取每个列的第一部分。
示例:第10到50列看起来像-> 10:a:b:c:d:e:f
(我只希望每个列中都包含“ 10”)。
到目前为止,我有以下内容,但是我不确定如何为拆分和打印a [1]部分做一定范围的列,所以这里我只有第10列,但是我希望它一直做同样的事情到第50列。
输入示例:
X 2 3 4 5 6 7 8 9 10:a:b:c 11:d:e:f 12:g:h:i (all the way to 50)
示例输出:
X 2 4 5 10 11 12 (all the way to 50)
码:
awk '$1 == "X" {print $1, $2, $4, $5, split($10,a,":"), a[1]}' file.txt > test.txt
我想我会有所不同。与其在数组中的字段10到50中捕获第一个用“:”定界的子字段,不如直接重写这些字段。
$1 == "X" {
$3=""
for (i=6; i<=9; i++)
$i=""
for (i=10; i<=NF; i++)
$i=substr($i,0,index($i,":")-1)
print
}
$3
这里的处理有点弱;awk没有消除列的真正解决方案。如果您无法处理额外的分隔符,则可能需要更详细的说明:
$1 == "X" {
s=""
for (i=10; i<=NF; i++)
s=s OFS substr($i,0,index($i,":")-1)
print $1,$2,$4,$5 s
}
此解决方案在最后一个命令前缺少逗号,s
因为OFS将作为该字符串的第一个字符包含在内。这是一个优化,以避免不必要的测试,但是如果您愿意,也可以转而避免使用临时变量:
$1 == "X" {
printf "%s", $1 OFS $2 OFS $4 OFS $5
for (i=10; i<=NF; i++)
printf "%s", OFS substr($i,0,index($i,":")-1)
printf ORS
}
我们printf
在这里使用以避免ORS的虚假出现。
我这样测试:
$ cat input
X 2 3 4 5 6 7 8 9 10:a:b 11:c:d 12:e:f:g
$ awk -f test.awk input
X 2 4 5 10 11 12
谢谢你的回答!我不断收到语法错误:bash:意外令牌'('附近的语法错误
没关系,一旦我将脚本另存为可执行文件,它就会起作用。谢谢!
好极了!我也固定了测试输出-
-f
如果您指定程序文件,awk需要该选项。