[英]How to write multiple “and”, “or” conditions in a if-statement in shell?
[英]Shell not evaluating multiple conditions in IF statement
我想根據兩個條件將文件分類到文件夾中,但它不會評估這兩個條件。 條件基於從與特定主題相對應的文本文件 (index.txt) 中讀取的值,並且值被編碼為 0 或 1
Subid DX SEX
XXXX 0 0
YYYY 1 0
代碼如下
#!/bin/sh
d=XXXX
dx=$(awk '{if($1=='$d'){print $2}}' index.txt)
sex=$(awk '{if($1=='$d'){print $3}}' index.txt)
if [ "$dx" == "0" ] && [ "$sex" == "0" ];then
commands
fi
我試過使用雙括號[[ <condition 1> ]] && [[ <condition 2> ]];
, 折疊括號if [ <condition1> && <condition2> ];
、括號和使用-eq
而不是==
,但它們仍然沒有計算並且沒有打印錯誤。 我錯過了什么?
調試 shell 腳本時最有用的技巧之一是set -x
(或使用sh -x
運行整個腳本)。 這使得 shell 在執行每個命令時打印它們的等價物,因此您可以更好地了解實際發生的情況以及它是否符合您的預期。 讓我們在你的腳本上試試:
$ sh -x reader.sh
+ d=XXXX
++ awk '{if($1==XXXX){print $2}}' index.txt
+ dx=
++ awk '{if($1==XXXX){print $3}}' index.txt
+ sex=
+ '[' '' == 0 ']'
請注意,它將dx
和sex
設置為空字符串。 如果您查看正在執行的 awk 腳本,您就會明白為什么: XXXX
周圍沒有雙引號,因此 awk 將其視為變量名,而不是要與之匹配的文字字符串。
您可以添加雙引號,但這並不是最好的方法; 將文字字符串粘貼到可執行代碼(在本例中為 awk 腳本)中可能會導致部分字符串被誤認為是可執行代碼,這可能會產生非常奇怪/糟糕的后果。 做這種事情的更好方法是將數據作為 data傳遞,通過使用 awk 的-v
選項設置一個變量,然后使用它。 就像是:
$ awk -v d="XXXX" '{if($1==d){print $2}}' index.txt
0
嘿,它打印了正確的東西! 所以這是使用它的腳本版本:
#!/bin/sh
d=XXXX
dx=$(awk -v d="$d" '{if($1==d){print $2}}' index.txt)
sex=$(awk -v d="$d" '{if($1==d){print $3}}' index.txt)
if [ "$dx" = "0" ] && [ "$sex" = "0" ];then
commands
fi
需要注意的是名為awk的變量d
有一個名為shell變量沒有內在的聯系d
; -vd="$d"
位將 shell 變量復制到同名的 awk 變量中。 此外,我在比較中將==
切換為僅=
,因為這是[ ]
的標准字符串相等運算符。 bash 允許==
作為同義詞,但並非所有 shell 都這樣做; 如果您是專門為 bash 編寫的,則應使用特定的 bash shebang 行( #!/bin/bash
或#!/usr/bin/env bash
)而不是#!/bin/sh
。
(實際上,我建議使用 bash shebang,因為如果您不清楚什么是標准 shell 語法以及什么是 bash 擴展名,那么您可能無論如何都不會進行可移植的編寫,因此明確請求 bash 更安全。如果您重新這樣做,您不妨切換到[[ ]]
而不是[ ]
,因為它避免了[ ]
表達式遭受的許多語法奇怪。)
問題不在於您的條件,而在於您使用 awk 設置的變量。
嘗試以下設置您的變量:
#!/bin/sh
d=XXXX
dx=$(awk '{if ($1 ~ /'$d'/) print $3}' index.txt)
sex=$(awk '{if ($1 ~ /'$d'/) print $3}' index.txt)
if [ "$dx" = "0" ] && [ "$sex" = "0" ];then
echo "works"
fi
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.