【问题标题】:bash: 'map' function arguments?bash:'map'函数参数?
【发布时间】:2018-07-16 14:55:06
【问题描述】:

在将列表转发到其他命令之前,通过某种转换(例如连接每个字符串)本质上“映射”bash 参数列表的最优雅方法是什么?想到使用xargs,但我似乎无法概念化如何做到这一点。

function do_something {
    # hypothetically
    for arg in "$@"; do
        arg="$arg.txt"
    done

    command "$@"
}

do_something file1 file2 file3

结果是调用command file1.txt file2.txt file3.txt

【问题讨论】:

    标签: bash xargs


    【解决方案1】:

    您所做的大部分都是正确的,只是您需要使用数组来存储新参数:

    function do_something {
        array=()
        for arg in "$@"; do
            array+=("$arg.txt")
        done
    
        command "${array[@]}"
    }
    
    do_something file1 file2 file3
    

    【讨论】:

    • 太棒了。这绝对比this answer中显示的字符串操作更具可读性(和优雅)
    【解决方案2】:

    您可以对map 使用以下定义,该定义类似于许多函数式编程语言中的定义(例如pythonhaskell):

    function map
    {
        local f="$1"
        shift # consume first argument
        for arg
        do
            "$f" "$arg" # assuming `f` prints a single line per call
        done
    }
    

    这是您在示例中使用它的方式。这里command可能是本地定义的函数:

    function do_something
    {
        local IFS=$'\n' # only split on newlines when word splitting
        result=($(map suffix "$@")) # split into lines and store into array
        command "${result[@]}" # call command with mapped arguments.
    }
    function suffix
    {
        echo "$@".txt
    }
    
    do_something file1 file2 file3
    

    这是do_something 的另一种写法。这里command必须存在于$PATH中:

    function do_something
    {
        map suffix "$@" | xargs command # call command with mapped arguments. 
    }
    

    主要的缺点是要在另一个函数中使用结果,你需要弄乱IFS 来分割换行符,或者通过管道输入 xargs;如果您的地图输出包含换行符,那么这两种方法都会完全失败。

    【讨论】:

      【解决方案3】:

      为了将参数“转发”到其他命令,有几种方法。试试这个脚本:

      printargs() {
        echo "Args for $1:"
        shift
        for a in "$@"; do
         echo "    arg: -$a-"
        done
      }
      
      printargs dolstar $*
      printargs dolstarquot "$*"
      printargs dolat $@
      printargs dolatquot "$@"
      

      并使用测试参数调用它:

      ./sc.sh 1 2 3
      dolstar 的参数:
      参数:-1-
      参数:-2-
      参数:-3-
      dolstarquot 的参数:
      参数:-1 2 3-
      dolat 的参数:
      参数:-1-
      参数:-2-
      参数:-3-
      dolatquot 的参数:
      参数:-1-
      参数:-2-
      参数:-3-

      如果参数包含空格,情况会有所不同:

      ./sc.sh 1 "2 3"
      dolstar 的参数:
      参数:-1-
      参数:-2-
      参数:-3-
      dolstarquot 的参数:
      参数:-1 2 3-
      dolat 的参数:
      参数:-1-
      参数:-2-
      参数:-3-
      dolatquot 的参数:
      参数:-1-
      参数:-2 3-

      dolatquot“$@”是唯一正确转发参数的版本。否则,如另一个答案所示,您可以操纵参数并通过数组或单个字符串构造一个新列表。

      【讨论】:

        猜你喜欢
        • 2013-05-11
        • 1970-01-01
        • 2015-03-29
        • 1970-01-01
        • 1970-01-01
        • 2021-10-05
        • 1970-01-01
        • 2011-09-27
        相关资源
        最近更新 更多