2016-07-27 8 views
2

Ich möchte Funktionsargumente ändern, bevor Sie sie an eine nächste Funktion übergeben.Ändern von Funktionsargumenten in Bash

firstfunction() { 
    # change "-f" to "--format" in arguments 
    secondfunction "[email protected]" 
} 

Ich habe versucht, in ein Array zu konvertieren, ändern Sie das Array und zurück in Argumente konvertieren. Aber es sieht so kompliziert aus. Ist es möglich, es einfacher zu machen?

UPDATE: spezifischer sein ...

firstfunction data.txt -f "\d+" 

secondfunction data.txt --format "\d+" 
+0

@anubhava Der Einfachheit halber nehmen wir an, ich brauche kurze Optionen für lange Optionen zu ändern: -f -> --format, -x -> --execute. –

Antwort

1

Dies ist ein überraschend schwieriges Problem. Bash ist einfach nicht gut darin, mit (leicht) komplexen Datenstrukturen wie Arrays zu arbeiten.

Ich denke, die einzig denkbare robuste Lösung wird eine Schleife benötigen. Dies ist die einfachste Art, wie ich mich vorstellen kann:

function firstfunction { 
    local -A map=(['-f']='--format'); 
    local -a args=(); 
    local arg; 
    for arg in "[email protected]"; do 
     if [[ -v map[$arg] ]]; then 
      args+=("${map[$arg]}"); 
     else 
      args+=("$arg"); 
     fi; 
    done; 
    echo ${args[@]+"${args[@]}"}; ## replace echo with secondfunction to run 
}; 
firstfunction; 
## 
firstfunction a b; 
## a b 
firstfunction x -f -fff -f-f -fxy x-f \ -f -f\ -f; 
## x --format -fff -f-f -fxy x-f -f -f --format 

Mit ${args[@]+"${args[@]}"} statt nur "${args[@]}" für den Endausbau um die schlecht beraten Design-Entscheidung arbeitet die bash Entwickler ein leeres Array als „ungebundene Variable“ ablehnen wenn Sie die nounset Option (set -u) aktiviert haben. Siehe Bash empty array expansion with `set -u`.


Alternative:

function firstfunction { 
    local -A map=(['-f']='--format'); 
    local -a args=("[email protected]"); 
    local -i i; 
    for ((i = 0; i < ${#args[@]}; ++i)); do 
     if [[ -v map[${args[i]}] ]]; then 
      args[i]="${map[${args[i]}]}"; 
     fi; 
    done; 
    echo ${args[@]+"${args[@]}"}; ## replace echo with secondfunction to run 
}; 
+1

Danke @bgoldst! Ich habe mit @ anubhavas Lösung gespielt und realisiert, dass ich eigentlich genereller brauche. –

+0

Nicht für das Picken, aber 'firstfunction -fabc' ist ein gültiges Optionsargument, um' abc' mit '-f' zu senden. Um generisch zu sein, sollte es '--format abc' oder' --format = abc' werden. – anubhava

+0

Sie können hier eine viel einfachere Schleife verwenden: 'für arg in" $ @ "; mach es – chepner

1

Sie können getopts zuverlässigen Parse und Prozess optionale Argumente wie diese verwenden nennen sollte:

firstfunction() { 
    OPTIND=1 
    local arr=() 
    while getopts "f:x:" opt; do 
     case $opt in 
     f) arr+=("--format $OPTARG");; 
     x) arr+=("--execute $OPTARG");; 
     esac 
    done 
    echo "${arr[@]}"; # or call second function here 
} 

firstfunction -fabc -x foobar 
--format abc --execute foobar 

firstfunction -fabc -xfoobar 
--format abc --execute foobar 

firstfunction -f abc -xfoobar 
--format abc --execute foobar 
+0

Ja, das ist richtig @bgoldst. Für idiotensicheren Weg, um dies zu handhaben, würde ich vorschlagen, eine Schleife mit 'while getopts' – anubhava

Verwandte Themen