我有一个简短的shell函数将人类可读的字节单元转换为字节整数,例如,
10米到10000000 4kb到4000 1kib到1024 2gib到2147483648
以下是代码:
dehumanise() {
for v in "$@"
do
echo $v | awk \
'BEGIN{IGNORECASE = 1}
function printpower(n,b,p) {printf "%u\n", n*b^p; next}
/[0-9]$/{print $1;next};
/K(B)?$/{ printpower($1, 10, 3)};
/M(B)?$/{ printpower($1, 10, 6)};
/G(B)?$/{ printpower($1, 10, 9)};
/T(B)?$/{ printpower($1, 10, 12)};
/Ki(B)?$/{printpower($1, 2, 10)};
/Mi(B)?$/{printpower($1, 2, 20)};
/Gi(B)?$/{printpower($1, 2, 30)};
/Ti(B)?$/{printpower($1, 2, 40)}'
done
}
我在互联网上找到了代码,我对awk并不那么自信。该功能正常,直到我几天前重新安装我的MacBook。现在它抛出一个错误
awk:接下来在函数printpower的源代码行2中的函数内是非法的 背景是 function printpower(n,b,p){printf“%u \ n”,n * b ^ p; >>>下一个}<<<
据我了解,接下来用于awk直接结束记录。因此,在这种情况下,它将结束awk语句,因为它只有一个输入。
我试图将下一个语句简单地移到printpower(...)之后;接下来。 但这导致函数根本没有输出。
有人可以帮我修复awk声明吗?
#awk --version
awk版本20121220
macOS awk版
没有输出的东西可能是macOS awk版本的问题。我用gawk安装并替换它:
brew install gawk
brew link --overwrite gawk
现在没有下一个声明就能正常工作。
答案 0 :(得分:1)
软件设计基础 - 避免控制反转。在这种情况下,您不希望某些从属功能突然负责您的整个处理控制流程,并且 IT 决定"拧紧所有人,我' m 强>决定跳到下一个记录"。所以是的,不要将next
放在函数中!话虽如此,POSIX并没有说你不能在一个函数中使用next但是它没有明确说你可以这样一些awk实现(显然你正在使用的那个)决定在gawk和其他一些awks允许时禁止它它
您的脚本(IGNORECASE
)中也有特定于gawk的代码,因此无论如何它只能与gawk一起使用。
以下是如何真正编写脚本以在任何awk中工作:
awk '
{ $0=tolower($0); b=p=0 }
/[0-9]$/ { b = 1; p = 1 }
/kb?$/ { b = 10; p = 3 }
/mb?$/ { b = 10; p = 6 }
/gb?$/ { b = 10; p = 9 }
/tb?$/ { b = 10; p = 12 }
/kib$/ { b = 2; p = 10 }
/mib$/ { b = 2; p = 20 }
/gib$/ { b = 2; p = 30 }
/tib$/ { b = 2; p = 40 }
p { printf "%u\n", $2*b^p }
'
如果您愿意,可以在主体中的每次; next
分配后添加p
,但它不会影响输出,只需提高效率,如果您的输入是数千线条很长。
答案 1 :(得分:0)
如消息所示,您无法在函数中使用my_reader[client_list[i]]
。您必须在每个函数调用之后放置它:
next
但如果你不介意额外的CPU周期,你可以让 /KB?$/ { printpower($1, 10, 3); next; }
/MB?$/ { printpower($1, 10, 6); next; }
...
测试剩余的模式(在任何地方没有awk
)。请注意,next
周围的括号是多余的,我已将其删除。
B
答案 2 :(得分:0)
您可以在函数中使用控制变量,然后检查变量的值以决定在主例程中使用下一步。
# MAIN
{
myfunction(test)
if (result == 1) next
# result is not 1, just continue
# more statements
}
function myfunction(a) {
# default result is 0
result = 0
# some test
if ($1 ~ /searchterm/) {
result = 1
}
}