awk 拆分更多列并打印第一个单词

Posted

技术标签:

【中文标题】awk 拆分更多列并打印第一个单词【英文标题】:awk split more columns and print first word 【发布时间】:2021-09-29 19:43:09 【问题描述】:

我有逗号分隔的文件,我想以相同的拆分条件 split($column,a,"-") 将第 15 列拆分为 $NF(第 15 列到最后一列)并打印每个拆分列 a[1]。我不能从第 n 个到最后一个列循环并为每个列打印。

awk -F',' -v OFS="\t" 'for(i;$15<i<$NF,i+1);split($i,a,"_"); print ???' file.csv

文件打印表格第 15 列示例:

NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx

我的期望:

NBPF1,NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

谢谢。

【问题讨论】:

我认为你很接近:for(i=15;i&lt;=$NF;++i)split($i,a,"-"); print a[1] $NF是最后一个字段内容,NF是数字,注意区别。 【参考方案1】:

使用您显示的示例,请尝试遵循awk 代码。更改i=15 或任何您想要开始循环的字段,直到awk 代码后面的当前行的最后一个字段。

awk '
BEGIN
  FS=OFS=","


  value=""
  for(i=1;i<=NF;i++)
    split($i, a, /-/)
    value=(value?value OFS:"")a[1]
  
  print value

'  Input_file

【讨论】:

【参考方案2】:
$ awk 'gsub(/-[^,]*/,"")1' file
NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

$ sed 's/-[^,]*//g' file
NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

如果这不是您真正需要的,请编辑您的问题以提供更具代表性的示例输入/输出。

【讨论】:

【参考方案3】:

你可以使用这个awk:

awk 'BEGIN FS=OFS="," for(i=1; i<=NF; ++i) 
split($i, a, /-/); printf "%s%s", a[1], (i<NF ? OFS : ORS)' file

NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

i=1 更改为i=15 或您要开始从中提取- 分隔值的任何字段位置。

【讨论】:

【参考方案4】:
cut -d, -f15- file | sed 's/-[^,]*//g'

【讨论】:

【参考方案5】:

另一个例子,纯粹使用正则表达式替换:

awk 'gsub(/^([^,]*,)14/,"")gsub(/-[^,]*(,|$)/,"\t")' file.csv

这个刚刚从 $0 中删除了前 14 列,然后在剩余的每一列中删除了 - 和它之后的内容。 用 gnu awk 测试过。

示例输入:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx
1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx
1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF0-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF9-chr1-16583499-16583796-MedEx

输出:

NBPF1   NBPF1   NBPF1   NBPF1   NBPF1
NBPF1   NBPF1   NBPF1   NBPF1   NBPF1
NBPF0   NBPF1   NBPF1   NBPF1   NBPF9

【讨论】:

输出不应该在每一行显示一个尾随制表符吗? 好点,只是为了代码简洁我没有在这里处理:) @rowboat【参考方案6】:

使用awk你可以得到它:

awk -v RS='[-,]' 'NR%5==1' file       
NBPF1                                   
NBPF1
NBPF1
NBPF1
NBPF1

或者正是你所期望的:

awk -v RS='[-,]' 'NR%5==1printf "%s%s", sep, $0; sep="," ENDprint ""' file
NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

【讨论】:

【参考方案7】:

换一个怎么样? 如果您只想要拆分后的第一部分,则无需拆分并保存到临时变量:

awk -F, -v OFS="\t" 'for(i=15;i<=NF;i++)printf "%s" OFS, gensub(/-.*/,"",1,$i);print ""' file.csv

如果会在最右边创建一个空列,如果你不想这样,那么使用这个:

awk -F, -v OFS="\t" 'for(i=15;i<NF;i++)printf "%s" OFS, gensub(/-.*/,"","g",$i);print gensub(/-.*/,"","g",$NF)' file.csv

如果您希望输出以逗号分隔,请将 "\t" 替换为 ,。 它适用于 GNU awk,需要实现 gensub

【讨论】:

以上是关于awk 拆分更多列并打印第一个单词的主要内容,如果未能解决你的问题,请参考以下文章

shell习题第10题:打印每个单词的字数

拆分特定的 PySpark df 列并创建另一个 DF

cut 或 awk 命令打印第一行的第一个字段

AWK - 比较后打印完整的输入字符串

将字符串拆分为第一个单词和其余文本?

哇 |拆分列并使用子字符串映射