awk在空值情况下添加分号

5

我有一个文件,每行的长度都不同。例如:

a; 1; 2; 3; 4;  
b; 11; 22;  
c; 122; 233; 344; 45; 56;  
d; 13;  
e; 144; 25; 36; 47; 58; 69;

我尝试生成一个文件,以分号作为分隔符,其中每一行有相同数量的值。例如:

a; 1; 2; 3; 4; ; ;  
b; 11; 22; ; ; ; ;  
c; 122; 233; 344; 45; 56; ;  
d; 13; ; ; ; ; ;  
e; 144; 25; 36; 47; 58; 69;

我尝试了不同的awk方法,但是我太新手了,无法批量正确完成。

awk '{if( $4 == ""){print ";"}else{print $4}}' testtest.txt

我希望 swarm intelligence 可以帮助我解决这个问题。
4个回答

6

根据您提供的示例,请尝试以下awk代码。这更像是通用代码,在第一次读取整个Input_file时获取最多字段数,然后在找到它后将其传递给第二个Input_file,并将每行的NF值分配给NF值,该值根据需要给出总字段数,并为新添加的字段放置;

awk -v FS='; ' -v OFS='; ' '
FNR==NR{
  nf=(nf>NF?nf:NF)
  next
}
{
  $nf=$nf
}
1
'  Input_file  Input_file

注意:我将Input_file两次传递到awk代码中。 - RavinderSingh13
1
好的解决方案。如果您感兴趣,我已经发布了一个带有技巧的答案,可以避免重复输入文件名。 - blhsing

5
让你的记录至少包含8个字段:
awk -F '; *' -v OFS='; ' '{$8 = $8} 1'

限制:

  • 需要静态指定所需字段的数量,因此您需要已经知道输入文件中有多少字段(请参见@RavinderSingh13 答案以了解确定字段数量的通用方法)。

  • 例如,如果有一个包含9个字段的记录,则代码将不会将其削减为8个字段。


3
@RavinderSingh13的答案可以解决问题,但需要在参数列表中重复输入文件名,可以通过修改ARGCARGV来避免此问题:
awk '
BEGIN{
  FS=OFS="; "
}
NR==1{
  ARGV[ARGC++] = FILENAME
}
FNR==NR{
  nf=(nf>NF?nf:NF)
  next
}
{
  NF=nf
}
1
' testtest.txt

不要在脚本主体中执行 ARGV[ARGC++] = FILENAME,否则每个输入行都必须测试 NR==1,这是一种不必要的性能损失(以及更多的代码)。相反,在 BEGIN 部分中执行 ARGV[ARGC++] = ARGV[1] - Ed Morton

-1
     gawk 'BEGIN { FS = (OFS = "; ") "*" } NF = 8'
-or-
     mawk NF=8 FS='; *' OFS='; '     
a; 1; 2; 3; 4; ; ; 
b; 11; 22; ; ; ; ; 
c; 122; 233; 344; 45; 56; ; 
d; 13; ; ; ; ; ; 
e; 144; 25; 36; 47; 58; 69;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接