Bash中没有空格的字符串连接

Teo*_*tus 3 string bash

我正在尝试编写一个简单的bash脚本来计算目录中的文件数,然后将名为file <#files>的新文件添加到目录的末尾.我目前的尝试是:

name="out"
num=$(ls -l|wc -l)
echo foo > "${name}${num}"
Run Code Online (Sandbox Code Playgroud)

但是,这给了我一堆空格,产生了文件名out 12.为什么会出现空格,如何在不创建空格的情况下连接这些字符串?

mkl*_*nt0 9

OS X(和一般类似BSD的系统)上,wc -l左空间将数字填充到8个字符,例如_______7(_出于技术原因在此处表示空格).

(如果你使用wc的输出不带引号echo-例如 echo $(wc -l <<<'dummy'),你将不会看到填充,因为shell会'吃’的前导空格;如果双引号的命令替换,你会看到他们: echo "$(wc -l <<<'dummy')"

也就是说,出于稳健性和性能的原因,你最好ls不要wc同时使用它们.使用globbing捕获数组中的所有文件名并使用该数组的元素计数:

name='out'
files=( * ) # collect all filenames in array

echo foo > "${name}${#files[@]}" # use array-element count
Run Code Online (Sandbox Code Playgroud)

注意:默认情况下,*包括隐藏的物品,就像OP的ls命令(因为它不包括-A-a).
使用shopt -s dotglob包括隐藏的项目太多.
此外,如果根本没有匹配的项目,Bash将按原样返回模式,即*; 让Bash返回空字符串,使用shopt -s nullglob.


通常,如果您确实发现需要从命令输出和/或Bash变量修剪前导和尾随空格:

  • 修剪存储在Bash变量中的,请使用read:

     # Single-line value:
     val='  a   b  '
     read -r val <<<"$val" # $val now contains 'a   b'
    
     # Multi-line value:
     # Note: Trims leading and trailing whitespace including newlines, but 
     # preserves *any* interior whitespace, including empty and all-whitespace lines.
     val=$'\n \t  one\n  \ntwo\n  \n'
     read -r -d '' val <<<"$val" # $val now contains $'one\n  \ntwo'
    
    Run Code Online (Sandbox Code Playgroud)
  • 要将命令输出作为管道的一部分或stdin/a 文件中的修剪:

    • 如果要修剪的值没有内部空白,或者你想要确保/不介意内部空白被标准化为每个单独的空格,则管道xargs(这是有效的,因为xargs在将输入解析为单词后,将它们传递给echo默认实用程序 - 没有shell参与); 结果始终是一个单一的输出线 ; 警告:xargs删除嵌入的引号和\实例,除非你\- 它们:

      val=$(ls | wc -l | xargs) # $val now contains trimmed count
      
      Run Code Online (Sandbox Code Playgroud)
    • 如果保留线内部空白是重要的,请使用sed; 注意, -不同于read -r d ''以上-这是一个基于LINE-溶液,所以输入线的数量将被保留,包括前缘和后空或全部空白线,具有所有空白线修剪到的人(假定GNU桑达或BSD SED):

      echo $'\nfoo \n \n bar \n' | sed -E 's/^[[:blank:]]+|[[:blank:]]+$//g'
      # -> $'\nfoo\n\nbar'
      
      Run Code Online (Sandbox Code Playgroud)