如何在 UNIX shell 脚本中比较 2 个字符串?

如何在 UNIX shell 脚本中比较 2 个字符串?

我有一个变量,用于存储字符串,即 sed 命令的输出。仅当该字符串值与其他 2 个字符串中的任何一个匹配时,我才想执行一组命令。

我使用了下面的代码。

#! /bin/ksh
request=”Request”
fault=”Fault”
while read lines; do
    category=`echo $lines|sed -n -e 's/.*Summary: Value//p'| awk '{print $1}'`
    if [ ! -z "$category" ]
    then
        if($category = $request)
        then
            echo $category
        fi
     fi
done<content.txt

但这给了我一个错误:

sample.sh: Request: not found

变量类别将具有 valueRequest或 valueOrder

有人可以指出错误或解决方案吗?

if 内部的 if 被消除并且echo $category将打印精确的字符串值。

答案1

简单的答案是这样你可以使用以下语法:

if [ "$category" = "$request" ]

间距很重要。旁注,您应该使用最近的方法进行命令替换和替换(请参阅第1条POSIX 文章):

category=`echo $lines|sed -n -e 's/.*Summary: value//p'| awk '{print $1}'`

这样

category=$(echo $lines|sed -n -e 's/.*Summary: value//p'| awk '{print $1}')

答案2

其他人已经指出了您if语句中的语法错误。

我还想评论一下这样一个事实:您似乎使用了印刷双引号 ,而不是普通的双引号"。您也不需要sed通过该命令替换将 的输出存储在单独的变量中。相反,awk直接从输出中读取:

#!/bin/ksh

sed -n 's/.*Summary: Value//p' <content.txt | awk '{ print $1 }' |
while IFS= read -r category; do
    case $category in
        Request|Fault)
            printf '%s\n' "$category"
            ;;
        Breakfast)
            echo 'Yum'
            ;;
        *)
            printf 'Unknown category: %s\n' "$category"
    esac
done

或者,如果您对 - 语句更满意if

#!/bin/ksh

sed -n 's/.*Summary: Value//p' <content.txt | awk '{ print $1 }' |
while IFS= read -r category; do
    if   [ "$category" = 'Request' ] || [ "$category" = 'Fault' ]; then
        printf '%s\n' "$category"
    elif [ "$category" = 'Breakfast' ]; then
        echo 'Yum'
    else
        printf 'Unknown category: %s\n' "$category"
    fi
done

请注意,无需测试字符串是否为空。只要您将空字符串与另一个字符串进行比较就可以没有问题始终引用变量扩展

或者,如果您的脚本除了执行以下操作之外什么也不做:

#!/bin/ksh

sed -n 's/.*Summary: Value//p' <content.txt | awk '
    $1 == "Request" || $1 == "Fault" { print $1;    next }
    $1 == "Breakfast"                { print "Yum"; next }
                                     { printf("Unknown category: %s\n", $1) }

有关的:

答案3

我们应该使用if 条件来[代替(

尝试:

 if [ "$category" = "$request" ]
  • ()用于执行命令并检查退出代码。
  • []用于检查表达式。

我希望你已经从 MS-word 复制了脚本,因为它具有非 UNIX 字符

request=”Request”
fault=”Fault”

将此编辑为

request="Request"
fault="Fault"

答案4

除了所有其他答案所说的之外,

  1. awk是一个非常强大的程序。您很少需要将其与另一个文本格式命令结合起来。例如,
    sed -n -e 's/.*摘要:值//p' | awk '{打印$1}'
    可以转换为
    awk '{ if (sub(/.*Summary: Value/, "")) print $1 }'
  2. 您应该始终引用 shell 变量(例如"$lines""$category""$request"),除非您有充分的理由不这样做,并且您当然你知道你在做什么。
  3. 作为拘萨罗南达指出, 使用 shell 循环处理文本被认为是不好的做法。正如我上面所说,awk是一个非常强大的程序。我假设您了解您的脚本一次读取文件一行,并为每一行调用awk(和!)一次。sed在没有明确指出的情况下,Kusalananda 为您提供了示例解决方案,该解决方案对整个文件运行awk( 和) 一次;sed最后一个将所有逻辑放入awk脚本中,而不是 shell 代码中。正如您的问题所示,如果您所做的只是打印字符串,那么这可能是最好的方法。但是,即使您需要根据输入运行其他命令,也可以system()使用awk.您的任务的复杂性将是决定哪种方法更好的一个因素。

相关内容