Bash
循環輸入並在bash中執行命令的通用函式?
我試圖創建一個循環輸入並執行命令的函式——不管它們是如何分隔的。
function loop { # Args # 1: Command # 2: Inputs for input in "$2" ; do $1 $input done }
declare -a arr=("1" "2" "3") $ loop echo "$arr[@]" 1 $ loop echo 1 2 3 1 $ loop echo $arr 1
但是根據這個答案,
for .. in ..
適用於數組:for item in "${arr[@]}" ; do echo "$item" done
它也適用於空格分隔的值:
for item in 1 2 3 ; do echo "$item" done
簡而言之,我如何在傳遞參數時獲得
"${arr[@]}"
效果1 2 3
。是否可以將這種循環概念擴展到任何類型的分隔項,例如
\n
文件等分隔內容?在 Python 中我們有一個概念iterators
,在 bash 中是否有類似的東西?
您沒有正確呼叫數組。
$arr
只會擴展至數組中的第一個元素,並將擴展至第一個元素並附加$arr[@]
文字字元串。[@]
要呼叫數組的所有元素,請使用:
"${arr[@]}"
您遇到的另一個問題是
$2
僅包含第二個位置參數,您嘗試在其中迭代第 3、第 4、第 5 等。它們都將儲存在$@
.為了實現您的目標,您可以執行以下操作:
function loop { local command=$1 shift for i in "$@"; do "$command" "$i" done }
這將設置
command
為第一個位置參數,然後移位,以便$@
可以用來循環剩餘的參數。然後你只需要正確呼叫數組:$ declare -a arr=("element1" "element2" "element3") $ loop echo "${arr[@]}" element1 element2 element3 $ loop printf 'hello ' 'world\n' hello world $ loop touch file1 file2 file3 $ ls file1 file2 file3
如果您希望此函式能夠接受各種分隔符,您可以執行以下操作:
function loop { local command=$1 local delim=$2 shift 2 set -- $(tr "$delim" ' ' <<<"$@") for i in "$@"; do "$command" "$i" done }
這意味著您必須通過第二個參數指定正在使用的分隔符,例如:
$ loop echo '|' 'one|two|three' one two three $ loop echo '\n' "$(printf '%s\n' 'one' 'two' 'three')" one two three
但是,這有一些錯誤(如果您指定自定義分隔符,它仍將由空格分隔)