Есть ли более чистый способ добавить «else if» к условному присваиванию в Awk и т. Д.? - PullRequest
4 голосов
/ 14 сентября 2010

Некоторые языки, такие как сценарий 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

... который использует условное присваивание для сокращения синтаксиса.

Но, скажем, вы хотели также предложить $ 1 от всех предметов свыше 20 долларов и 2 доллара от предметов более 40 долларов.Ну, на языке, подобном 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) Существует ли не-kludge способ сделать многоусловное назначение в сценарии awk?

Чтобы уточнить: Я говорю исключительно о сокращении для назначения (<...>? <...>: <...>; нетрадиционное условное присваивание, о котором я уже знаю, как выполнять c-подобные составные присваивания в сценарии Awk. В качестве примечания, почему яЯ мог бы использовать сокращение, я думаю, что заслуга очевидна - что он короткий. Но, как и регулярные выражения, вы можете написать хорошее описание того, что ваш запутанный синтаксис делает для потомков.

Ответы [ 3 ]

2 голосов
/ 15 сентября 2010

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, et al и Ruby (который также поддерживает форму ?:) поддерживают этот стиль (показывает версию Bash):

[[ condition ]] && do_if_true || do_if_false

, что можно сделать в сложной форме.Это может выполнять действия в дополнение к заданиям.

b) нет, не без явного if / else (или прибегая к еще большему хладнокровию творчеству.

0 голосов
/ 15 сентября 2010

(а) Я так думаю

(б) Да


Как это бывает, ваш код "С" почти законен.Следующая слегка подправленная версия прекрасно работает как программа 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)
}

Я вынул точки с запятой, но ничего плохого не произойдет, если вы оставите их в ...

0 голосов
/ 15 сентября 2010

На самом деле, в C также есть оператор ?, так что вы можете сделать то же самое (беспорядочно) с C.

Однако вы, по сути, делаете там код только для записи.Если бы вы не сказали мне, что сделало это заявление awk, было бы очень трудно понять это.Почему бы просто не пойти дальше и использовать if?

Вы будете благодарить себя через 6 месяцев, когда обнаружите необходимость настроить его.

...