我的文件如下:
overlay
我的目标是: 用“-”(共有8个字段)将空单元格/空格/缺少值的列替换为
使用awk命令执行此操作时面临的问题是字段分隔符在每一行中都在不断变化。
我到目前为止所做的事情: 我提取了具有某些字段模式的行,并将它们放置在不同的文件中。例如:我将方案3,6和9放在一个文件中,其余的放在另一个文件中,以使处理数据更加容易。我现在拥有的是:
文件1:
aufs
文件2:
overlay2
预期输出:
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(将awk与FIELDWIDTHS结合使用):
Scenario 3 6 12.95
Scenario 6 6 8.70
Scenario 9 5 5.06
案例2(使用sed命令):
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
答案 0 :(得分:1)
不幸的是,在这种情况下,您需要仔细计算字符列。这是您提供的输入的代码-您可能需要调整实际输入文件的数字。
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个空格。您可能只想用一排空格代替它。
答案 1 :(得分:1)
为此,您可以在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 ""}'
答案 2 :(得分:1)
使用GNU awk和while(m_running) {
sd_bus_message *m = NULL;
r = sd_bus_process(m_bus, &m);
if (r < 0) {
//error handling
}
r = sd_bus_wait(m_bus, (uint64_t)-1);
if (r < 0) {
//error handling
}
}
变量根据字段长度分割字段:
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
。如果没有,则该字段保持不变。