當awk接收到“0”作為輸入,在某些情況下它的行為有所不同。程式碼如下:
var=$1
echo ""; echo -n 'o/p of $1=$1 ==>'; echo $var | awk '$1=$1'
echo "";echo -n 'o/p of {$1=$1;print} ==>';echo $var | awk '{$1=$1;print}'
echo "";echo -n 'o/p of $1==$1 ==>';echo $var | awk '$1==$1'
echo "";echo -n 'o/p of {$1==$1;print} ==>';echo $var | awk '{$1==$1;print}'
輸出與「0」(數字零):
[root@host ~]# sh /tmp/te.sh 0
o/p of $1=$1 ==>
o/p of {$1=$1;print} ==>0
o/p of $1==$1 ==>0
o/p of {$1==$1;print} ==>0
[root@GORJALA ~]#
輸出與「1」(第一):
[root@host ~]# sh /tmp/te.sh 1
o/p of $1=$1 ==>1
o/p of {$1=$1;print} ==>1
o/p of $1==$1 ==>1
o/p of {$1==$1;print} ==>1
[root@host ~]#
var=0; echo $var | awk '$1=$1'
為什麼我使用and時會出現差異var=1; echo $var | awk '$1=$1'
?除了 之外,所有數字都工作正常0
。
版本:
- GNU bash,版本 4.2.46
- GNU Awk 4.0.2
- coreutils-8.22-24.el7.x86_64
答案1
賦值是一個表達式,因此它有一個值-與被賦值的值相同。因此,「z = 1」是值為 1 的表達式。
所以
echo 0 | awk '$1=$1'
此模式的計算結果為 0 (FALSE)echo 1 | awk '$1=$1'
print
此模式的計算結果為 1 (TRUE),並且執行預設操作
答案2
我認為這不是數值的問題:標準轉換可以解決這個問題(至少在這裡)。
OP 顯示了四種不同的 awk 程式碼,所有變體都是:pattern { action }
(一) 1 美元 = 1 美元
這會將 $1 重新分配給自己。它不是布林測試,它是無操作(實際上),並且傳回值 $1。如果 $1 是 0,則模式為錯誤的和預設值列印動作被完全跳過。如果 $1 非零,則輸入被列印。
(b) { $1 = $1;列印; }
這會將 $1 重新分配給自己,這也是一個空操作。在沒有模式的情況下,執行操作並輸入總是列印。
(c) $1 == $1
這是一個布林表達式永遠真實。 0 是 0,1 是 1(土豚就是土豚)。在沒有動作的情況下,輸入是總是列印。
(d) { $1 == $1;列印; }
沒有模式。比較結果為真布林值,布林值被丟棄。輸入是總是列印。
答案3
現有答案無法解釋原因
echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'
將全部列印0
,但是
echo 0 | awk '$0'
echo 000 | awk '$0'
不會列印任何內容,但在所有情況下,模式表達式的計算結果都是0
。
為什麼0
一種情況為真,另一種情況為假?
這是因為“字段變數”(運算符的結果$
)被視為特例,和(如果可能)會自動轉換為數字字串,如果在數值上等於0
,則在布林上下文中使用時將被視為 false:
字串值應被視為數位串如果它來自以下其中之一:
字段變數
getline()
來自函數的輸入
FILENAME
ARGV
數組元素
ENVIRON
數組元素
split()
函數所建立的數組元素命令列變數賦值
來自另一個數字字串變數的變數賦值
[如果它看起來像一個數字,請閱讀整個描述這裡]
另請閱讀RATIONALE
為什麼需要數字字串的概念和這種特殊情況,尤其是關於諸如“ echo 0 000 | awk '$1==$2'
true,但不是”之類的比較echo 0 | awk '$1=="000"'
。
作為另一個怪癖,請注意,至少在某些實現中,$0
如果對子字段的賦值導致重新計算(當前輸入記錄),則它會丟失其神奇的“數字字串”屬性:
$ echo 0 | gawk '{$1=0} $0'
0
這似乎沒有被標準涵蓋,儘管它與標準 awk 所基於的 nawk/bwk 的行為相匹配(但不是 mawk 的行為)。
此外,允許 awk 實現將輸入中的NAN
,INF
和識別INFINITY
為相應的浮點數,儘管對此的支援參差不齊且不一致。您可能仍然被咬傷,例如。
echo But his daughter named Nan | awk '$NF'
不在 FreeBSD 的 awk 中列印任何內容(bwk、original-awk)。
答案4
因為 $0 是整個記錄(完整行),$1,$2,是領域(通常用空格分隔)在其中。