我的文件看起来像这样:
Scenario 1 0.20 0.00 0.00 r
Scenario 2 0.08 0.34 & 0.34 r
Scenario 3 6 12.95
Scenario 4 0.00 0.08 0.00 0.00 & 0.35 r
Scenario 5 0.07 0.08 & 0.42 r
Scenario 6 6 8.70
Scenario 7 0.00 0.07 0.00 0.00 & 0.42 r
Scenario 8 0.31 0.28 & 0.70 f
Scenario 9 5 5.06
我的目标是:使用“ - ”替换空单元格/空格/缺少值的列(总共有8个字段)
我使用awk命令执行此操作时遇到的问题是字段分隔符随着每一行而不断变化。
到目前为止我做了什么:我已经提取了具有某些字段模式的行并将它们放在不同的文件中。例如:我已将场景3,6和9放在一个文件中,其余放在另一个文件中,以便更容易处理数据。我现在拥有的是:
档案1:
Scenario 3 6 12.95
Scenario 6 6 8.70
Scenario 9 5 5.06
文件2:
Scenario 1 0.20 0.00 0.00 r
Scenario 2 0.08 0.34 & 0.34 r
Scenario 4 0.00 0.08 0.00 0.00 & 0.35 r
Scenario 5 0.07 0.08 & 0.42 r
Scenario 7 0.00 0.07 0.00 0.00 & 0.42 r
Scenario 8 0.31 0.28 & 0.70 f
预期产量:
Scenario 1 - - 0.20 - 0.00 0.00 r
Scenario 2 - - 0.08 - 0.34 & 0.34 r
Scenario 3 6 12.95 - - - -
Scenario 4 - 0.00 0.08 0.00 0.00 & 0.35 r
Scenario 5 - - 0.07 - 0.08 & 0.42 r
Scenario 6 6 8.70 - - - -
Scenario 7 - 0.00 0.07 0.00 0.00 & 0.42 r
Scenario 8 - - 0.31 0.28 & 0.70 f
Scenario 9 5 5.06 - - - -
案例1(使用带有FIELDWIDTHS的awk):
$ awk 'BEGIN { FIELDWIDTHS="37 3 7 7 7 9 9 "} {for(i=1;i<=NF;++i){printf $i"|"};print""}' main1.txt
| I_BLENDER_0/R_137/CLK (SDFFX2_HVT) | | | 0.20 | | 0.00 | 0.00 r
| I_BLENDER_0/R_137/Q (SDFFX2_HVT) | | | 0.08 | | 0.34 & | 0.34 r
| I_BLENDER_0/n2757 (net) | 6 | 12.95|
| I_BLENDER_0/U4847/A1 (AND2X1_LVT) | | 0.00 | 0.08 | 0.00 | 0.00 & | 0.35 r
| I_BLENDER_0/U4847/Y (AND2X1_LVT) | | | 0.07 | | 0.08 & | 0.42 r
| I_BLENDER_0/n2616 (net) | 6 | 8.70 |
| I_BLENDER_0/U1/A4 (NAND4X0_HVT) | | 0.00 | 0.07 | 0.00 | 0.00 & | 0.42 r
| I_BLENDER_0/U1/Y (NAND4X0_HVT) | | | 0.31 | | 0.28 & | 0.70 f
案例2(使用sed命令):
$ sed "s/^\(.\{,36\}\)$/\1`echo -$_{1..30}|tr -d '-'`/;
s/^\(.\{38\}\) /\1-/;
s/^\(.\{43\}\) /\1-/;
s/^\(.\{50\}\) /\1-/;
s/^\(.\{57\}\) /\1-/;
s/^\(.\{64\}\) /\1-/;
s/^\(.\{73\}\) /\1-/;
s/ *$//"
I_BLENDER_0/R_137/CLK (SDFFX2_HVT) - - 0.20 - 0.00 0.00 r
I_BLENDER_0/R_137/Q (SDFFX2_HVT) - - 0.08 - 0.34 & 0.34 r
I_BLENDER_0/n2757 (net) 6 12.95
I_BLENDER_0/U4847/A1 (AND2X1_LVT) - 0.00 0.08 0.00 0.00 & 0.35 r
I_BLENDER_0/U4847/Y (AND2X1_LVT) - - 0.07 - 0.08 & 0.42 r
I_BLENDER_0/n2616 (net) 6 8.70
为此,您可以在Gnu awk中使用FIELDWIDTHS
:
基本上,我们将您的线条分成恒定宽度的字段。以下显示正确分割线条:
$ awk 'BEGIN{ FIELDWIDTHS="13 25 2 7 7 7 9 9"}
{for(i=1;i<=NF;++i){printf $i"|"};print""}' file
Scenario 1 | | | | 0.20 | | 0.00 | 0.00 r|
Scenario 2 | | | | 0.08 | | 0.34 & | 0.34 r|
Scenario 3 | | 6 | 12.95| ||||
Scenario 4 | | | 0.00 | 0.08 | 0.00 | 0.00 & | 0.35 r|
Scenario 5 | | | | 0.07 | | 0.08 & | 0.42 r|
Scenario 6 | | 6 | 8.70 |||||
Scenario 7 | | | 0.00 | 0.07 | 0.00 | 0.00 & | 0.42 r|
Scenario 8 | | | | 0.31 | | 0.28 & | 0.70 f|
Scenario 9 | | 5 | 5.06 |||||
所以我们需要做的就是在需要时用短划线替换空字段。
$ awk 'BEGIN{ FIELDWIDTHS="13 24 3 7 7 7 9 9"}
{s=$1$2}
{s=s ($3~/^[[:blank:]]*$/?" - ":$3)}
{s=s ($4~/^[[:blank:]]*$/?" - ":$4)}
{s=s ($5~/^[[:blank:]]*$/?" - ":$5)}
{s=s ($6~/^[[:blank:]]*$/?" - ":$6)}
{s=s ($7~/^[[:blank:]]*$/?" - ":$7)}
{s=s ($8~/^[[:blank:]]*$/?" - ":$8)}
{print s}' file
这给了:
Scenario 1 - - 0.20 - 0.00 0.00 r
Scenario 2 - - 0.08 - 0.34 & 0.34 r
Scenario 3 6 12.95 - - - -
Scenario 4 - 0.00 0.08 0.00 0.00 & 0.35 r
Scenario 5 - - 0.07 - 0.08 & 0.42 r
Scenario 6 6 8.70 - - - -
Scenario 7 - 0.00 0.07 0.00 0.00 & 0.42 r
Scenario 8 - - 0.31 - 0.28 & 0.70 f
Scenario 9 5 5.06 - - - -
备注:
%-5.2f
格式编写的。这就是为什么数字12.95
不对齐。 (%6.2f
会更好)注意:如果你玩一下,你实际上可以做得更短。但你有点失去了对正在发生的事情的感觉。
awk 'BEGIN{ FIELDWIDTHS="13 23 5 7 7 7 9 9"}
{for(i=3;i<=NF;++i)$i=$i~/^[[:blank:]]*$/?" -":$i}
{printf "%-13s%-23s%-5s%-7s%-7s%-7s%-9s%-9s\n",$1,$2,$3,$4,$5,$6,$7,$8}' file
甚至更短
awk 'BEGIN{ FIELDWIDTHS="36 5 7 7 7 9 9"; split(FIELDWIDTHS,a)}
{for(i=1;i<=NF;++i) printf "%-*s",a[i], ($i~/^ *$/?" -":$i); print ""}'
不幸的是,在这种情况下,您需要仔细计算字符列。以下是您提供的输入代码 - 您可能需要调整实际输入文件的数字。
sed "s/^\(.\{,78\}\)$/\1`echo -$_{1..78}|tr -d '-'`/;
s/^\(.\{38\}\) /\1-/;
s/^\(.\{43\}\) /\1-/;
s/^\(.\{50\}\) /\1-/;
s/^\(.\{57\}\) /\1-/;
s/^\(.\{64\}\) /\1-/;
s/^\(.\{73\}\) /\1-/;
s/ *$//" input_file
这里,第一行在行尾添加空格,以防行在到达78个字符之前终止 - 然后由替换利用。在链替换的最后,删除任何尾随空格。
第一行中看起来凌乱的表达式echo -$_{1..78}|tr -d '-'
只产生了78个空格。您可能只想用一长串空格替换它。
使用GNU awk和FIELDWIDTHS
变量根据字段长度分割字段:
awk 'BEGIN{
FIELDWIDTHS="38 4 7 7 7 9 6"
colnr=split(FIELDWIDTHS,a," ")
}
{
for(i=1;i<=colnr;i++){
$i=sprintf("%-"a[i]"s",((!$i&&$i!=0)||$i~/^ *$/?"-":$i))
}
}1' file
Scenario 1 - - 0.20 - 0.00 0.00 r
Scenario 2 - - 0.08 - 0.34 & 0.34 r
Scenario 3 6 12.95 - - - -
Scenario 4 - 0.00 0.08 0.00 0.00 & 0.35 r
Scenario 5 - - 0.07 - 0.08 & 0.42 r
Scenario 6 6 8.70 - - - -
Scenario 7 - 0.00 0.07 0.00 0.00 & 0.42 r
Scenario 8 - - 0.31 - 0.28 & 0.70 f
Scenario 9 5 5.06 - - - -
BEGIN
块将数组a
设置为所有字段的长度,并将字段数存储在变量colnr
中。
默认块循环遍历所有字段并使用sprintf()
函数重写它们。
如果该字段仅包含空白$i~/^ *$/
或不存在!$i&&$i!=0
,请将其替换为-
。如果没有,该领域保持不变。