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にも似ていますか?

ベストアンサー1

配列が正しく呼び出されませんでした。 $arr配列の最初の要素にのみ拡張され、$arr[@]リテラル文字列が追加される最初の要素に展開されます[@]

配列のすべての要素を呼び出すには、次のようにします。"${arr[@]}"

もう1つの問題は、$22番目の位置パラメータのみが含まれており、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
}

つまり、2番目のパラメータで使用する区切り文字を指定する必要があります。たとえば、次のようになります。

$ loop echo '|' 'one|two|three'
one
two
three
$ loop echo '\n' "$(printf '%s\n' 'one' 'two' 'three')"
one
two
three

ただし、これにはいくつかのバグがあります(カスタム区切り文字を指定すると、まだスペースで区切られます)。

おすすめ記事