我想基于两个条件将文件分类到文件夹中,但是它不会同时评估这两个条件。条件基于从文本文件(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
代替==
,但是它们仍然没有评估,也没有错误正在打印。我想念什么?
答案 0 :(得分:2)
调试外壳程序脚本时最有用的技巧之一是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脚本)中,可能会将字符串的某些部分误认为是可执行代码,这可能会带来真正的怪异/不良后果。进行此类操作的更好方法是使用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
请注意,名为d
的awk变量与名为d
的shell变量没有内在联系; -v d="$d"
位将shell变量复制到同名的awk变量中。另外,在比较中,我将==
切换为=
,因为这是[ ]
中的标准字符串相等运算符。 bash允许==
作为同义词,但并非所有的shell都这样做。如果您是专门为bash编写的,则应使用特定的bash shebang行(#!/bin/bash
或#!/usr/bin/env bash
)而不是#!/bin/sh
。
(实际上,我建议使用bash shebang,因为如果您不清楚标准的shell语法和bash扩展名是什么,那么您可能无论如何都无法移植,因此显式请求bash更加安全。如果这样做的话,最好改用[[ ]]
而不是[ ]
,因为它避免了[ ]
表达式所遭受的许多语法怪异。)
答案 1 :(得分:0)
问题不在于您的条件,而是与您的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