【问题标题】:How to check if a string has spaces in Bash shell如何检查字符串在 Bash shell 中是否有空格
【发布时间】:2010-12-01 05:35:11
【问题描述】:

假设一个字符串可能类似于"a b '' c '' d"。如何检查字符串中是否包含单引号/双引号和空格?

【问题讨论】:

  • 为什么要这样做?如果您尝试检查“无效”文件名,则可以改为修复脚本以支持带有空格或引号的文件名。例如。
  • 您是说您想知道:a) 空格周围有单/双引号 b) 单/双引号和空格一起 c) 完全不同的东西?
  • 只是检查一个字符串是否有单引号,是否有空格
  • 要检查字符串是否只有空格、制表符或换行符,请尝试:[[ $string = *[$" \t\n"]* ]]

标签: string bash shell if-statement


【解决方案1】:

您可以这样做,无需任何反斜杠或外部命令:

# string matching

if [[ $string = *" "* ]]; then
  echo "string contains one or more spaces"
else
  echo "string doesn't contain spaces"
fi

# regex matching

re="[[:space:]]+"
if [[ $string =~ $re ]]; then
  echo "string contains one or more spaces"
else
  echo "string doesn't contain spaces"
fi

基于这个benchmark,字符串匹配比正则表达式快得多。


相关:

【讨论】:

  • 最佳最新答案,因为它专门回答了问题 - 字符串中的空格 - 通过提供两个可移植且在代码审查期间非常容易理解的选项。请像@codeforester 这样的人保持简单;最好的软件永远是。
  • 正则表达式版本更通用,因为它还可以找到 \t 和 \n 和 \r。 [:space:] "空格、换页、换行、回车、水平制表符、垂直制表符等空白字符" oreilly.com/library/view/oracle-regular-expressions/0596006012/…
【解决方案2】:

这个呢:

[[ $var == ${var//[ \"]/_} ]] && echo "quotes or spaces not found"

或者如果你喜欢这个:

if [[ $var == ${var//[ \"]/_} ]] ; then  
   echo "quotes or spaces not found" 
else
   echo "found quotes or spaces"
fi

解释: 在使用下划线对所有引号和空格进行即时无损字符串替换后,我正在评估变量 ${var} 和变量 ${var} 本身之间的比较。

示例:

${var// /_}  # Substitute all spaces with underscores

以下代码将方括号(空格和引号)之间的所有字符替换为下划线。请注意,引号必须用反斜杠保护:

${var//[ \"]/_}  

【讨论】:

  • 我喜欢这种语法的使用,但是您已经翻转了搜索并且正在寻找与 OP 要求相反的内容。应该提到!=
【解决方案3】:
[[ "$str" = "${str%[[:space:]]*}" ]] && echo "no spaces" || echo "has spaces"

【讨论】:

  • 请注意,对于那些好奇的人来说,这不会检测制表符或换行符
【解决方案4】:

你可以在 bash 中使用正则表达式:

string="a b '' c '' d"
if [[ "$string" =~ \ |\' ]]    #  slightly more readable: if [[ "$string" =~ ( |\') ]]
then
   echo "Matches"
else
   echo "No matches"
fi

编辑:

出于上述显而易见的原因,最好将正则表达式放在变量中:

pattern=" |'"
if [[ $string =~ $pattern ]]

双方括号内不需要引号。它们不能用在右边或正则表达式更改为文字字符串。

【讨论】:

  • 最干净的 IMO,对我来说,我还添加了选项卡,但看起来有点时髦,因为我不得不把美元报价扔在那里 pattern=" |'"$'|\t' - 有没有更清洁的方法?
  • @nhed:在单个字符的情况下,您可以使用字符模式而不是管道字符交替。这可能不那么难看:pattern=$'[ \'\t]'。您还可以使用变量:tab=$'\t'; pattern=" |'|$tab" 或文字选项卡(不利于可读性),方法是使用 Ctrl-V-Tab 键入它。
【解决方案5】:

我确实想知道为什么没有人提到 [:space:] 集。通常您不仅对检测空格字符感兴趣。我经常需要检测任何空白,例如标签。 “grep”示例如下所示:

$ echo " " | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace"
Has Whitespace
$ echo "a" | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace"
Has no Whitespace

【讨论】:

  • 对于那些对此解决方案感兴趣的人,我的grep 通知我character class syntax is [[:space:]], not [:space:]。否则,很好的解决方案!
  • 由于问题被标记为“bash”,因此无需启动另一个进程来测试字符串:case "$String" in *[[:space:]]*) echo "match" ;; esac
【解决方案6】:
function foo() {
    echo "String: $*"
    SPACES=$(($#-1))
    echo "Spaces: $SPACES"
    QUOTES=0
    for i in $*; do
        if [ "$i" == "'" ]; then
            QUOTES=$((QUOTES+1))
        fi
    done
    echo "Quotes: $QUOTES"
    echo
}

S="string with spaces"
foo $S
S="single' 'quotes"
foo $S
S="single '' quotes"
foo $S
S="single ' ' quotes"
foo $S

产量:

String: string with spaces
Spaces: 2
Quotes: 0

String: single' 'quotes
Spaces: 1
Quotes: 0

String: single '' quotes
Spaces: 2
Quotes: 0

String: single ' ' quotes
Spaces: 3
Quotes: 2

【讨论】:

    【解决方案7】:

    可移植的方式是使用grep

    S="a b '' c '' d"
    if echo $S | grep -E '[ "]' >/dev/null
    then
      echo "It's a match"
    fi
    

    ...有点难看,但保证可以在任何地方工作。

    【讨论】:

    • 使用 grep 中的 -q 选项,不再需要 >/dev/null。好一点。
    【解决方案8】:
    case "$var" in  
         *\ * )
               echo "match"
              ;;
           *)
               echo "no match"
               ;;
    esac
    

    【讨论】:

    • 我在吹毛求疵,但你不需要引用 $var。
    • @Idelic,如果 $var 未设置会怎样?
    • 没有引号完全可以,将打印“不匹配”。
    • 感谢您引用它并为一般脚本树立了一个很好的例子,即使在这个特定的例子中它并不是绝对必要的。
    • 这不会检测标签等
    【解决方案9】:
    string="a b '' c '' d"
    if [ "$string" == "${string//[\' ]/}" ]
    then 
       echo did not contain space or single quote
    else
       echo did contain space or single quote
    fi
    

    【讨论】:

      【解决方案10】:

      类似的方法怎么样:

      $ A="some string"; echo $A | grep \  | wc -l
      1
      $ A="somestring"; echo $A | grep \  | wc -l
      0
      

      ?

      【讨论】:

        猜你喜欢
        • 2010-12-16
        • 2011-03-19
        • 1970-01-01
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-10
        相关资源
        最近更新 更多