【问题标题】:How to remove extra spaces in bash?如何删除bash中的多余空格?
【发布时间】:2012-10-17 00:57:24
【问题描述】:

如何去除变量HEAD中多余的空格?

HEAD="    how to  remove    extra        spaces                     "

结果:

how to remove extra spaces

【问题讨论】:

  • 您真的要删除HEAD 中的空格,还是只是将不带空格的$HEAD 扩展提供给另一个命令? shell 提供了更好的工具来控制扩展的输出,而不是仅仅改变变量的工具。
  • 如你所见here: tr -s " "

标签: bash removing-whitespace


【解决方案1】:

试试这个:

echo "$HEAD" | tr -s " "

或者您可能想将其保存在变量中:

NEWHEAD=$(echo "$HEAD" | tr -s " ")

更新

要删除前导和尾随空格,请执行以下操作:

NEWHEAD=$(echo "$HEAD" | tr -s " ")
NEWHEAD=${NEWHEAD%% }
NEWHEAD=${NEWHEAD## }

【讨论】:

  • 谢谢。它不会删除空格或末尾或开头的空格:-(
  • 在技术上你不能只使用NEWHEAD=${echo $HEAD}
  • 您可以启用shopt -s extglob,然后只需使用NEWHEAD=${NEWHAED/+( )/ } 删除内部空格。
  • 当你不引用 $HEAD 时,调用 tr 有什么意义,所以 bash 会进行分词并因此折叠自身的空格?
【解决方案2】:

试试这个:

echo '    how to  remove    extra        spaces                     ' | sed 's/^ *//g' | sed 's/$ *//g' | sed 's/   */ /g'

HEAD="    how to  remove    extra        spaces                     "
HEAD=$(echo "$HEAD" | sed 's/^ *//g' | sed 's/$ *//g' | sed 's/   */ /g')

【讨论】:

    【解决方案3】:

    以下是我将如何使用 sed:

    string='    how to  remove    extra        spaces                     '
    echo "$string" | sed -e 's/  */ /g' -e 's/^ *\(.*\) *$/\1/'
    
    => how to remove extra spaces   # (no spaces at beginning or end)
    

    第一个 sed 表达式用一个空格替换任何超过 1 个空格的组,第二个表达式删除任何尾随或前导空格。

    【讨论】:

      【解决方案4】:

      利用不引用变量的分词效果

      $ HEAD="    how to  remove    extra        spaces                     "
      $ set -- $HEAD
      $ HEAD=$*
      $ echo ">>>$HEAD<<<"
      >>>how to remove extra spaces<<<
      

      如果您不想使用位置参数,请使用数组

      ary=($HEAD)
      HEAD=${ary[@]}
      echo "$HEAD"
      

      不引用的一个危险副作用是filename expansion 将发挥作用。所以先关闭它,然后重新启用它:

      $ set -f
      $ set -- $HEAD
      $ set +f
      

      【讨论】:

      • 这应该是公认的答案。这个,或the answer from kojiro.
      • 请注意,行为取决于值IFS。使用默认的IFS,即$' \t\n',您还将用空格替换制表符和换行符。
      【解决方案5】:

      使用 awk:

      $ echo "$HEAD" | awk '$1=$1'
      how to remove extra spaces
      

      【讨论】:

        【解决方案6】:

        这匹马还没死:让我们继续打败它!*

        读入数组

        Other people 提到了read,但由于使用不带引号的扩展可能会导致不需要的扩展,因此使用它的所有答案都可以被视为或多或少相同。 You could do

        set -f
        read HEAD <<< $HEAD
        set +f
        

        或者你可以这样做

        read -rd '' -a HEAD <<< "$HEAD"  # Assuming the default IFS
        HEAD="${HEAD[*]}"
        

        带有参数扩展的扩展通配符

        $ shopt -s extglob
        $ HEAD="${HEAD//+( )/ }" HEAD="${HEAD# }" HEAD="${HEAD% }"
        $ printf '"%s"\n' "$HEAD"
        "how to remove extra spaces"
        

        *实际上没有马受到伤害——这只是一个简单问题得到六个以上不同答案的比喻。

        【讨论】:

        • 这是唯一真正有意义的答案。这是可悲的丑陋黑客和半破碎的答案反而被赞成......
        • 为了纪念这个答案(它避免了回声、外壳扩展和所有其他答案所陷入的所有其他陷阱),我删除了自己的错误答案。
        • 另外两个注意事项:read 需要-r 来防止处理反斜杠转义,-d "" 来规范换行符而不是在第一个换行符处截断。两个选项都需要在-a之前传递。
        • 您在应用@MichałGórny 的建议时引入了一个错误:read -rd'' -a HEAD 将不起作用,它需要是read -r -d '' -a HEADread -rd '' -a HEAD。此外,应该提到 IFS,因为这仅在 IFS 包含空格字符时才有效。
        • 谢谢,@Maxxim,已修复
        【解决方案7】:

        echo -e " abc \t def "|column -t|tr -s " "

        column -t 将:

        1. 删除行首和行尾的空格
        2. 将制表符转换为空格

        tr -s " " 会将多个空格压缩为单个空格


        顺便说一句,要查看整个输出,您可以使用 cat - -A:显示所有空格字符,包括制表符和 EOL:

        echo -e " abc \t def "|cat - -A

        输出:abc ^I def $

        echo -e " abc \t def "|column -t|tr -s " "|cat - -A

        输出: abc def$

        【讨论】:

          【解决方案8】:

          不带引号的回声变量可以满足您的要求:

          HEAD="    how to  remove    extra        spaces      "
          echo $HEAD
          
          # or assign to new variable
          NEW_HEAD=$(echo $HEAD)
          echo $NEW_HEAD
          

          输出:how to remove extra spaces

          【讨论】:

            【解决方案9】:

            我会使用tr 删除多余的空格,并使用xargs 修剪前后。

            TEXT="     This          is  some                             text   "
            echo $(echo $TEXT | tr -s " " | xargs)
            
            # [...]$ This is some text
            

            【讨论】:

              【解决方案10】:

              空格可以采用空格制表符的形式。尽管它们是非打印字符并且我们看不到,sed 和其他工具将它们视为不同形式的空白,并且只对您要求的内容进行操作。即,如果您告诉sed 删除 x 个 空格,它会这样做,但表达式将不匹配 制表符。反之亦然 - 将 tab 提供给 sed,它不会匹配 空格,即使它们的数量等于标签中的数量。

              一种可扩展性更强的解决方案,可用于删除 空格制表符形式的额外空间中的一个/两个strong>(我已经在您的样本变量中测试了两者的混合)是:

              echo $HEAD | sed 's/^[[:blank:]]*//g'
              

              或者我们可以加强@Frontear 关于使用xargs 的绝佳建议没有 tr

              echo $HEAD | xargs
              

              但是,请注意xargs 也会删除换行符。因此,如果您要 cat 一个文件并将其通过管道传输到 xargs,则所有额外的空格(包括换行符)都将被删除,并且所有内容都放在同一行;-)。

              上述两项在我的测试中都达到了你想要的结果。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-05-19
                • 1970-01-01
                • 2023-01-16
                • 2019-03-03
                • 1970-01-01
                • 2013-06-03
                • 2018-10-13
                相关资源
                最近更新 更多