用管道和括号分隔的 Bash 脚本数组

0 linux text-processing

我需要创建一个 bash 脚本来转换由 | 分隔的文本文件内容。和 ] ...

文本文件内容例如:

Col1|Col2|Col3|P1]P2]P3|D1]D2]D3||Col4 
Col3|ColA|ColA|PA]PB]|DA]DB]|ColD||
Run Code Online (Sandbox Code Playgroud)

所需的输出是:

Col1 Col2 Col3 P1 D1 0 Col4
Col1 Col2 Col3 P2 D2 0 Col4
Col1 Col2 Col3 P3 D3 0 Col4
Col3 ColA ColA PA DA ColD 0
Col3 ColA ColA PB DB ColD 0
Col3 ColA ColA 0 0 ColD 0
Run Code Online (Sandbox Code Playgroud)

已编辑:] 之后的空白列和空白数据都将替换为 0

谢谢你。

Rom*_*nov 5

您可以通过示例脚本来完成(我的不是最佳的,但可以工作)

awk -F'[]|]' '{
   print $1,$2,$3,$4,$7,$10
   print $1,$2,$3,$5,$8,$10
   print $1,$2,$3,$6,$9,$10 }' input_filename
Run Code Online (Sandbox Code Playgroud)

或者

awk -F'[]|]' '{
   for (i = 4; i <= 6; i++)
     print $1,$2,$3,$i,$(i+3),$10}' input_filename
Run Code Online (Sandbox Code Playgroud)

你可以改变输出域加入(默认为空)-v OFS=','

并感谢@steeldriver 一种更灵活的方式(具有内部字段分离)来完成这项工作:

awk -F'|' '{
  split($3,a,/]/); n = split($4,b,/]/); 
  for(i=1;i<=n;i++) print $1,$2,a[1],a[i+1],b[i],$5}' input_filename
Run Code Online (Sandbox Code Playgroud)

根据编辑的问题,如果您想用0(零)替换空字段,您可以使用以下脚本来完成:

awk -F'[]|]' '{ 
   for (i = 1; i <= 11; i++) if ($i == "") $i=0}
   {
   print $1,$2,$3,$4,$7,$10,$11
   print $1,$2,$3,$5,$8,$10,$11
   print $1,$2,$3,$6,$9,$10,$11 }' input_filename
Run Code Online (Sandbox Code Playgroud)

根据您的评论,脚本应如下所示:

awk -F'|' -v OFS="\t" '{
 n = split($4,D,"]"); split($5,E,"]");
 for (i = 1; i <= n; i++) {
     if (D[i] == "") D[i]=0;
     if (E[i] == "") E[i]=0;}
     print $1,$2,$3,D[i],E[i],$6,$7 }' input_file 
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过仅使用 `|` 作为 FS,然后在 `]` 上进一步拆分,例如 `awk -F'|' 来减少硬编码 '{split($3,a,/]/); n = split($4,b,/]/); for(i=1;i&lt;=n;i++) 打印 $1,$2,a[1],a[i+1],b[i],$5}'` 但是这仍然假设`$3` 和 `$4` 中的子字段 (3认同)