什么是最优雅的方式来实现' map'在将列表转发到其他命令之前,通过某些转换(例如连接每个字符串)的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
。
答案 0 :(得分:3)
你所做的大部分都是正确的,除了你需要使用一个数组来存储新的参数:
function do_something {
array=()
for arg in "$@"; do
array+=("$arg.txt")
done
command "${array[@]}"
}
do_something file1 file2 file3
答案 1 :(得分:1)
您可以为map
使用以下定义,该定义类似于许多功能编程语言(例如python,haskell)中的定义:
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;如果您的地图输出包含换行符,则这两种方法都会完全失败。
答案 2 :(得分:0)
为了将参数“转发”到其他命令,有几种方法。试试这个脚本:
printargs() {
echo "Args for $1:"
shift
for a in "$@"; do
echo " arg: -$a-"
done
}
printargs dolstar $*
printargs dolstarquot "$*"
printargs dolat $@
printargs dolatquot "$@"
并使用测试aguments调用它:
./ sc.sh 1 2 3
dolstar的争议:
arg:-1-
arg:-2-
arg:-3-
dolstarquot的参数:
arg:-1 2 3-
dolat的指针:
arg:-1-
arg:-2-
arg:-3-
dolatquot的参数:
arg:-1-
arg:-2-
arg:-3-
如果参数包含空格,事情会有所不同:
./ sc.sh 1“2 3”
dolstar的争议:
arg:-1-
arg:-2-
arg:-3-
dolstarquot的参数:
arg:-1 2 3-
dolat的指针:
arg:-1-
arg:-2-
arg:-3-
dolatquot的参数:
arg:-1-
arg:-2 3-
dolatquot “$ @”是唯一正确转发参数的版本。否则,如另一个答案所示,您可以操纵参数并通过数组或单个字符串构建新列表。