2015-11-26 2 views
4

Интересно, можно ли удалить переменную в awk. Для массива можно указать delete a[2], и индекс 2 массива a[] будет удален. Однако для переменной я не могу найти способ.Удалить переменную в awk

Ближайший я могу сказать, var="" или var=0.

Но, кажется, что значение по умолчанию несуществующей переменной 0 или False:

$ awk 'BEGIN {if (b==0) print 5}' 
5 
$ awk 'BEGIN {if (!b) print 5}' 
5 

Так мне тоже интересно, если можно различать переменную, которая устанавливается в 0 и переменная, которая не была установлена, потому что кажется, не:

$ awk 'BEGIN {a=0; if (a==b) print 5}' 
5 

ответ

5

Там нет операции, чтобы сбросить/DELE т. е. переменную. Единственный раз, когда переменная становится снята с охраны снова в конце вызова функции, когда это неиспользуемый аргумент функции используется в качестве локальной переменной:

$ cat tst.awk 
function foo(arg) { 
    if ((arg=="") && (arg==0)) { 
     print "arg is not set" 
    } 
    else { 
     printf "before assignment: arg=<%s>\n",arg 
    } 
    arg = rand() 
    printf "after assignment: arg=<%s>\n",arg 
    print "----" 
} 
BEGIN { 
    foo() 
    foo() 
} 

$ awk -f tst.awk file 
arg is not set 
after assignment: arg=<0.237788> 
---- 
arg is not set 
after assignment: arg=<0.291066> 
---- 

так что если вы хотите, чтобы выполнить какие-либо действия А, то задана переменная X а затем выполните действия B, вы можете инкапсулировать A и/или B в функции, используя X в качестве локального var.

Обратите внимание, что значение по умолчанию равно нулю или нулевому, а не нулю или false, так как это тип «числовая строка».

Вы тест для снято с переменным, сравнивая его как утративший нуль:

$ awk 'BEGIN{ if ((x=="") && (x==0)) print "y" }' 
y 
$ awk 'BEGIN{ x=0; if ((x=="") && (x==0)) print "y" }' 
$ awk 'BEGIN{ x=""; if ((x=="") && (x==0)) print "y" }' 

Если вам нужно иметь переменные вы удалить, то вы всегда можете использовать массив из одного элемента:

$ awk 'BEGIN{ if ((x[1]=="") && (x[1]==0)) print "y" }' 
y 
$ awk 'BEGIN{ x[1]=""; if ((x[1]=="") && (x[1]==0)) print "y" }' 
$ awk 'BEGIN{ x[1]=""; delete x; if ((x[1]=="") && (x[1]==0)) print "y" }' 
y 

, но ИМХО, что запутывает ваш код.

Каким будет прецедент для отключения переменной? Что бы вы сделали с этим, что вы не можете сделать с var="" или var=0?

+0

Все началось в [этот ответ] (http://stackoverflow.com/a/33942659/1983854) при попытке удалить переменную 'stack'. Для меня это выглядело немного странно, когда нужно было просто «жестко» «var =» «вместо простого удаления. – fedorqui

+0

Да, я понял, если стек был реализован как массив, вы должны удалить массив, но он реализован как строка, так почему бы вам не удалить его? Ответ в том, что это не так, как вы начинаете строку на любом языке. Конечно, вы всегда можете реализовать его как строку, хранящуюся полностью в 'stack [1]', а затем весело удалять 'stack', но это не улучшит читаемость вашего кода! –

+0

@EdMorton 'awk 'BEGIN {a = 0; if (a == b && length (b)> 0) print 5} '' он может работать? –

2

задана переменная расширяется до "" или 0, в зависимости от контекста, в котором оно является ева luated.

По этой причине я бы сказал, что это вопрос предпочтения и зависит от использования переменной.

Учитывая, что мы используем a + 0 (или немного спорные +a) в END блоке, чтобы заставить потенциально отключенные переменную a в числовой тип, я думаю, можно утверждать, что естественное «пустое» значение будет "".

Я не уверен, что есть слишком много, чтобы читать в тех случаях, когда вы показанными в этом вопросе, учитывая следующее:

$ awk 'BEGIN { if (!"") print }' 
5 

("" ложна, не удивительно)

$ awk 'BEGIN { if (b == "") print 5 }' 
5 

(переменная незадана оценивает равна "", так же, как 0)

+0

Ответьте на эту последнюю точку, не удаляя индекс, а также то, на что он указал в памяти - попробуйте '2 в a' после' delete a [2] '. –

+0

@Ed Я предполагаю, что для интерпретации вывода '2 в a' правильно потребовалось бы знание того, что делает тест (я не знаю!) –

+1

' a' - хеш-таблица, '2 в a' обращается место памяти, в которое вы попадаете, когда вы hash '2'. Если он заполнен, то «2 в a» преуспевает, иначе это не так. Когда вы говорите 'delete a [2]', вы освобождаете память в месте, на которое указывает хеширование '2'. –

Смежные вопросы