按换行符分割

按换行符分割

一直在使用不同的 bash 函数实现,能够处理参数中的单独行。

var1="
First Argument
A new line"

var2="
Second Argument
A new line"  

调用函数为

theone $var

禁止分词。

但在函数内部,我仍然必须引用$@.

theone ()
 {
  for vl in "$@"; do
    printf '%s\n' "$vl"
  done
 }

我想要的是按换行符分割。

答案1

theone $var对 中的每个单词调用split $var:第一个参数是First,第二个参数是Argument,第三个参数是A,依此类推。使用这种方法,您将丢失嵌入的换行符,并且与任何不带引号的变量一样,字符串中包含 shell 通配符 ( *, [, ], ?) 的任何单词都将进行通配并与当前目录中的名称进行匹配。诸如“Are you certain??”之类的字符串如果您surety在当前目录中调用了一个文件,则可以扩展为“您确定吗” 。一般来说,这不是一个好主意。

根据您的上一个问题我建议应该这样写theone "$var",其中不会发生分词,并且您有一个多行参数theone

如果您想$var单独处理每一行,我可以建议许多不同的构造。在每个中,printf编写该行是为了清楚地显示内部循环中正在处理的内容。将每个称为theone "$var"

  1. POSIX

    theone()
    {
        printf '%s\n' "$@" |
            while IFS= read -r vl
            do
                printf '## vl: %s ##\n' "$vl"
            done
    }
    
  2. 贝壳如bash

    theone()
    (
        for arg in "$@"
        do
            while IFS= read -r vl
            do
                printf '## vl: %s ##\n' "$vl"
            done <<< "$arg"
        done
    )
    
  3. 还有贝壳,例如bash

    theone()
    (
        for arg in "$@"
        do
            readarray -t vls <<<"$arg"
    
            for vl in "${vls[@]}"
            do
                printf '## vl: %s ##\n' "$vl"
            done
        done
    )
    

如果您确实只想传递单个(多行)参数,则可以通过删除最外层循环来简化所有这些。例如,最后一个可以这样写:

  1. 贝壳如bash

    theone()
    {
        local vls vl
    
        readarray -t vls <<<"$1"
    
        for vl in "${vls[@]}"
        do
            printf '## vl: %s ##\n' "$vl"
        done
    }
    

相关内容