是否有更干净的方法来添加“else if” Awk 等中的条件赋值?

发布于 2024-09-24 02:20:30 字数 1187 浏览 4 评论 0原文

某些语言(例如 awk 脚本)允许条件赋值。例如,假设您有一个格式如下的列表文件:

<item name, no spaces> <price as float>

例如

Grape 4.99
JuicyFruitGum 0.45
Candles 5.99

,您想对超过 1 美元的所有内容征税...您可以使用 awk 脚本:

awk '{a=($2>1.00)?$2*1.06:$2; print a}' prices.data

...它使用条件赋值来缩短语法。

但假设您还想为所有超过 20 美元的商品提供 1 美元折扣,为超过 40 美元的商品提供 2 美元折扣。在像 c 这样的语言中,您通常会执行以下操作:

if (price > 40.00) {
   price-=2; 
   price *= 1.06; 
}
else if ( price > 20.00 && price <= 40.00 ) {
   price--; 
   price *= 1.06; 
}
else if ( price > 1.00 ) {
   price*=1.06;
}

... 好吧,我发现您可以将 awk 或其他脚本语言混入 COMPOUND 赋值中。例如:

awk '{a=($2>1.00)?($2>20.00)?($2-1)*1.06:($2>40.00)?($2-2)*1.06:$2*1.06:$2; print a}' prices.data

我的问题是

a) 复合赋值(像这样)通常与支持条件赋值的脚本语言普遍兼容吗?
b) 是否有一种非拼凑的方法可以在 awk 脚本中进行多条件赋值?

澄清一下:我只讨论赋值的简写 (<...>?<...>:<...>;,而不是传统的条件赋值,我已经知道如何在 Awk 脚本中进行类似于 C 的复合赋值,作为旁注,至于为什么我可能使用速记,我认为它的优点是显而易见的 - 但就像正则表达式一样,您可能想要这样做。为了后代的利益,写下你令人困惑的语法的作用的一个很好的描述。

Certain languages like awk script allow for conditional assignments. For example, say you had a list file in the format:

<item name, no spaces> <price as float>

e.g.

Grape 4.99
JuicyFruitGum 0.45
Candles 5.99

And you wanted to tax everything over $1... you could use the awk script:

awk '{a=($2>1.00)?$2*1.06:$2; print a}' prices.data

...which uses conditional assignment to shorten the syntax.

But say you wanted to also offer $1 off all items over $20 and $2 off items over $40. Well in a language like c you would typically do something like:

if (price > 40.00) {
   price-=2; 
   price *= 1.06; 
}
else if ( price > 20.00 && price <= 40.00 ) {
   price--; 
   price *= 1.06; 
}
else if ( price > 1.00 ) {
   price*=1.06;
}

... well I discovered you could kludge awk or other scripting languages into COMPOUND assignment. e.g.:

awk '{a=($2>1.00)?($2>20.00)?($2-1)*1.06:($2>40.00)?($2-2)*1.06:$2*1.06:$2; print a}' prices.data

My questions are that

a) is compound assignment (like this) generally universally compatible with scripting languages that support conditional assignment?
b) Is there a non-kludge way to do multi-conditional assignment in awk script?

To clarify: I am talking exclusively about the shorthand for assignment (<...>?<...>:<...>;, not traditional conditional assignment, which I already know how to do c-like compound assignment for in Awk script. As a side note, as to why I might use shorthand, I think the merit is obvious -- that it's short. But like regexes, you might want to write a good description of what your confusing syntax does for posterity's sake.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜空下最亮的亮点 2024-10-01 02:20:30

a)

Bash、ksh 和 zsh 支持复合条件(三元)运算符(但 Bash 不支持浮点数):

for i in {3..5}; do for j in {2..6}; do for k in {2..4}; do
    (( a = i > j ? i > k ? j > k ? i * j : i * k : j * k : 0 ))
    echo $a
done; done; done

PHP 的三元运算符语法类似。

Python 的情况截然不同:

a = b if c else d if e else f if g else h

Bash 等和 Ruby(也支持 ?: 形式)支持这种样式(显示 Bash 的版本):

[[ condition ]] && do_if_true || do_if_false

可以以复合形式完成。除了分配之外,它还可以执行操作。

b)不,没有明确的if/else(或者诉诸更多的kludginess创造力。

a)

Bash, ksh and zsh support compound conditional (ternary) operators (Bash doesn't do floats, though):

for i in {3..5}; do for j in {2..6}; do for k in {2..4}; do
    (( a = i > j ? i > k ? j > k ? i * j : i * k : j * k : 0 ))
    echo $a
done; done; done

PHP's ternary operator syntax is similar.

Python's is quite different:

a = b if c else d if e else f if g else h

Bash, et al, and Ruby (which also supports the ?: form) support this style (showing Bash's version):

[[ condition ]] && do_if_true || do_if_false

which can be done in a compound form. This can perform actions in addition to assignments.

b) no, not without explicit if/else (or resorting to even more kludginess creativity.

成熟稳重的好男人 2024-10-01 02:20:30

实际上,C 也有 ? 运算符,因此您可以使用 C 做同样的(丑陋的)事情。

但是,您实际上是在那里编写只写代码。如果你没有告诉我那个 awk 语句做了什么,就很难弄清楚。为什么不直接使用 if 呢?

6 个月后,当您发现需要对其进行调整时,您会感谢自己。

Actually, C has the ? operator too, so you could do the same (fugly) thing with C.

However, you are essentially making write-only code there. If you hadn't told me what that awk statement did, it would be very difficult to figure it out. Why not just go ahead and use if?

You'll thank yourself in 6 months when you discover a need to tweak it.

五里雾 2024-10-01 02:20:30

(a) 我想是的

(b)


是的 碰巧,你的“C”代码几乎是合法的 awk。下面稍微调整的版本作为 awk 程序工作得很好...

/./ {
  price = $1
  if (price > 40.00) {
     price -= 2 
     price *= 1.06 
  } else if ( price > 20.00 && price <= 40.00 ) {
     price-- 
     price *= 1.06 
  } else if ( price > 1.00 ) {
     price *= 1.06
  }
  printf("%6.2f\n", price)
}

我把分号去掉了,但是如果你把它们留在里面,也不会发生什么坏事...

(a) I think so

(b) Yes


As it happens, your "C" code is almost legal awk. The following slightly tweaked version works just fine as an awk program...

/./ {
  price = $1
  if (price > 40.00) {
     price -= 2 
     price *= 1.06 
  } else if ( price > 20.00 && price <= 40.00 ) {
     price-- 
     price *= 1.06 
  } else if ( price > 1.00 ) {
     price *= 1.06
  }
  printf("%6.2f\n", price)
}

I took the semicolons out, but nothing bad happens if you leave them in...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文