bash脚本循环检查变量是否包含字符串-不工作

bash脚本循环检查变量是否包含字符串-不工作,bash,loops,Bash,Loops,我有一个脚本,可以将文件从一个s3存储桶复制到本地服务器,做一些事情并将其上传到另一个s3存储桶。 在最初的bucket中,我有几个文件夹,其中一个叫做“OTHER” 我不希望我的脚本在此文件夹上工作 我试图定义一个循环来检查路径字符串是否不包含字符串“OTHER”,然后继续执行其他命令,但由于某种原因,它不起作用。 我做错了什么 #!/bin/bash shopt -s extglob gcs3='s3://gc-reporting-pud-production/splunk_

我有一个脚本,可以将文件从一个s3存储桶复制到本地服务器,做一些事情并将其上传到另一个s3存储桶。 在最初的bucket中,我有几个文件夹,其中一个叫做“OTHER” 我不希望我的脚本在此文件夹上工作 我试图定义一个循环来检查路径字符串是否不包含字符串“OTHER”,然后继续执行其他命令,但由于某种原因,它不起作用。 我做错了什么

#!/bin/bash
shopt -s extglob

       gcs3='s3://gc-reporting-pud-production/splunk_printer_log_files/'
       gcs3ls=$((aws s3 ls 's3://gc-reporting-pud-production/splunk_printer_log_files/' --recursive) | sed 's/^.*\(splunk_printer.*\)/\1/g'| tr -s ' ' | tr ' ' '_')
       ssyss3=s3://ssyssplunk
       tokenFile=/splunkData/GCLogs/tokenFile.txt
       nextToken=$((aws s3api list-objects-v2 --bucket "gc-reporting-pud-production" --prefix splunk_printer_log_files/ --max-items 5) |grep -o 'NEXTTOKEN.*' |awk -F " " '{print $2}')
        newToken=$( tail -n 1 /splunkData/GCLogs/tokenFile.txt )
        waterMark=$(aws s3api list-objects-v2 --bucket "gc-reporting-pud-production" --prefix splunk_printer_log_files/ --max-items 5  --starting-token 
       $newToken|sed 's/^.*\(splunk_printer.*zip\).*$/\1/'|sed '1d'|sed '$d')
 while true; do
        for j in $waterMark ; do
                echo $j
                if [ "$j" != *"OTHER"* ]; then
                        gcRegion=$(echo $j |  awk  -F'/' '{print $2}')
                        echo "gcRegion:"$gcRegion
                        if [ "$gcRegion" != "OTHER" ]; then
                                gcTech=$(echo $j | awk  -F'/' '{print $3}')
                                echo "GCTech:"$gcTech
                                gcPrinterFamily=$(echo $j | awk  -F'/' '{print $4}')
                                echo "gcPrinterFamily:" $gcPrinterFamily
                                gcPrinterType=$(echo $j | awk  -F'/' '{print $5}')
                                echo "gcPrinterType:" $gcPrinterType
                                gcPrinterName=$(echo $j| awk -F'/' '{print $6}')
                                echo "gcPrinterName:" $gcPrinterName
                                gcFileName=$(echo $j| awk -F'/' '{print $7}'| awk -F'.zip' '{print $1}')
                                echo "gcFileName:" $gcFileName
                                cd /splunkData/GCLogs

 dir="/splunkData/GCLogs/$gcRegion/$gcTech/$gcPrinterFamily/$gcPrinterType/$gcPrinterName"
                                echo "dir:"$dir
                                mkdir -p  $dir
                                aws s3 sync $gcs3$gcRegion/$gcTech/$gcPrinterFamily/$gcPrinterType/$gcPrinterName/  $dir
                                find $dir  -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
                                aws s3 cp $dir $ssyss3/$gcRegion/$gcTech/$gcPrinterFamily/$gcPrinterType/$gcPrinterName/ --recursive --exclude "*.zip"


                                newToken=$( tail -n 1 /splunkData/GCLogs/tokenFile.txt )
                                nextToken=$(aws s3api list-objects-v2 --bucket "gc-reporting-pud-production" --prefix splunk_printer_log_files/ --max-items 5 --starting-token $newToken |grep -o 'NEXTTOKEN.*' |awk -F " " '{print $2}')
                                 waterMark=$(aws s3api list-objects-v2 --bucket "gc-reporting-pud-production" --prefix splunk_printer_log_files/ --max-items 5  --starting-token $newToken|sed 's/^.*\(splunk_printer.*zip\).*$/\1/'|sed '1d'|sed '$d')
                                echo "$nextToken" > "$tokenFile"
                        fi
                fi
        done


done

您需要使用双括号条件命令来打开
==
=到模式匹配中运算符:

if [[ "$j" != *"OTHER"* ]]; then
#  ^^                   ^^
或使用
case

case "$j" in
*OTHER*) ... ;;
*) echo "this is like an `else` block" ;;
esac

将您的代码粘贴到中,以便修复其他问题。

我认为格伦·杰克曼的做法是正确的。试试这个:

if [[ "$j" != *OTHER* ]]; then
[[]]是模式字符串匹配所必需的(您必须删除“)。case语句也是一个好主意。您可以完全放弃shell测试,使用grep,如下所示:

if 
  grep -q '.*OTHER.*' <<< "$j" 2>/dev/null
then
  ...
fi
根据BenjaminW的说法,[[]]中的$j左右的引号是不必要的。但是,
*OTHER*
周围的引号确实起到了很大的作用。请参见以下内容:

$ j="OTHER THINGS"
$ [[ $j == "*OTHER*" ]] ; echo "$j" matches '"*OTHER*"': $?
OTHER THINGS matches "*OTHER*": 1

$ [[ $j == *OTHER* ]] ; echo "$j" matches '*OTHER*': $?
OTHER THINGS matches *OTHER*: 0

告诉你所有你需要知道的问题。例如,你不能使用
$((cmd)| cmd)
;它必须是
$(cmd | cmd)
。嗨,谢谢你的回答。我使用了这个网站,改变了所有建议,但仍然是相同的结果。当你说“相同的结果”时,我们不知道这意味着什么,因为你所描述的都是“不起作用”“。你有错误吗?这是什么?嗨,谢谢你的回复,我尝试了这个选项,但仍然不起作用。这太糟糕了。祝你好运。除非你愿意分享一些细节。我将循环更改为:if[[“$j”!=OTHER];然后是路径:splunk_printer_log_files/OTHER/FDM/OTHER/Dimension Elite/P13851/2019-04-18T16:13:41.698Z_1.91.0.192_1.88.0.0_10.1.3810.zip显然它包含字符串“OTHER”,但它不退出循环,而是继续循环的其余部分code@sarit您必须使用
!=*OTHER*
用于部分匹配。我将循环更改为:if[[“$j”!=OTHER];这是路径:splunk_printer_log_files/OTHER/FDM/OTHER/Dimension Elite/P13851/2019-04-18T16:13:41.698Z_1.91.0.192_1.88.0.0_10.1.3810.zip显然它包含字符串“OTHER”,但它没有退出循环,而是继续其余的代码。你真的删除了星号吗?如果你想要这种逻辑,它应该是[[“$j”!=OTHER]],这里的引号并不重要。左侧在
[[]]
中引用,因此它们没有任何效果;在右边,它们只是围绕一个固定的字符串,也没有效果。@sarit,命令中有格式:用星号包围一个单词会产生斜体。在代码周围使用反勾号以准确显示它。@BenjaminW.-你说得对了一半-关于$j的报价无关紧要-
[[]]
在那里起作用。然而,
“*OTHER*”
与OTHER绝对不同。这就是我文章的重点。我将编辑以提供一个示例。
$ j="OTHER THINGS"
$ [[ $j == "*OTHER*" ]] ; echo "$j" matches '"*OTHER*"': $?
OTHER THINGS matches "*OTHER*": 1

$ [[ $j == *OTHER* ]] ; echo "$j" matches '*OTHER*': $?
OTHER THINGS matches *OTHER*: 0