bash skript for å utføre operasjonen på hver argument mot den siste argumentet

stemmer
0

Tenk deg at du ønsker å gjøre et bashscript som støtter ingen alternativer, men fungerer som cp, fordi cplevert av systemet godtar ikke flere kilder.

Bruken for systemets (hypotetisk og ødelagt) cper:

cp source target    # target may be a directory

Bruken for skriptet vil være:

cp.sh source... target    # target must be a directory

Her er et utgangspunkt for skriptet:

#!/bin/bash
tgt=$1
shift
for src in $@; do
    echo cp $src $tgt
done

Når kjøre med argumenter a b c d (merk at der målet), utganger det:

cp b a
cp c a
cp d a

Målet er å fikse skriptet til utgang dette stedet, samtidig koden enkel:

cp a d
cp b d
cp c d
Publisert på 22/09/2009 klokken 17:50
kilden bruker
På andre språk...                            


8 svar

stemmer
1

Hvorfor? Cp kommandoen gjør allerede det. Gjør en mann cp , og du vil se.

Hvis du fortsatt insisterer, her er to måter å få det siste argumentet. Metode 1: sted kommandolinje i en matrise, og ekstrahere den siste element:

arg=("$@")
last_arg=${arg[(($# - 1))]}

Den første linjen setter kommandolinjen argumentene inn i matrisen arg. Hvis kommandolinjen inneholder abcd så arg [0] == 'a', ... argv [3] == 'd'.

Den andre linjen ekstrahere den siste argumentet. Den (($ # - 1)) tar antall argumenter (4 i dette tilfellet), trekker en fra det (for å få 3). Dette uttrykket blir da:

last_arg=${arg[3]}

som peker til den siste argumentet.


Den andre metoden er ikke svært bærbar, det gjør bruk av det BASH_ARGV variable, som er $ @ men i omvendt rekkefølge. Hvis kommandolinjen er abcd deretter $ {BASH_ARGV [0]} == 'd', ... $ {BASH_ARGV [3]} == 'a':

last_arg=${BASH_ARGV[0]}

Jeg håper dette hjelper.

Svarte 22/09/2009 kl. 17:55
kilden bruker

stemmer
-1

Bruk denne til å trekke ut den siste parameter:

eval TGT = \ $$ #

så bare behandle på samme måte som du er og når du treffer $ # bare avslutte løkken

Her er whjole skriptet:

eval tgt=\$$#

for src in $@
do
 if [ "$src" == "$tgt" ];
 then
    exit
fi
echo cp $src $tgt
done

Ganske enkelt hvis du spør meg!

Svarte 22/09/2009 kl. 17:56
kilden bruker

stemmer
0
#!/bin/bash
t=(x "$@")
i=1; while [ $i -lt $# ]; do
  echo cp ${t[$i]} ${t[$#]}
  i=$(($i + 1))
done
Svarte 22/09/2009 kl. 18:12
kilden bruker

stemmer
1
#!/bin/bash
tgt="${@: -1}"    # get the last parameter
for src in "$@"; do
    if [[ $src != $tgt ]]; then
        echo cp "$src" "$tgt"
    fi
done
Svarte 22/09/2009 kl. 18:16
kilden bruker

stemmer
5

/test.bash Kilde 1 Kilde2 target1

#!/bin/bash

target=${!#} 

if [ ! -d $target ] ; then
    echo "$target must be a directory " >&2
    exit 1;
fi

args=("$@")
unset args[${#args[@]}-1]

for src in "${args[@]}"; do
    echo cp $src $target
done

vil produksjonen

cp source1 target1
cp source2 target1
Svarte 22/09/2009 kl. 18:59
kilden bruker

stemmer
2

Du kan bruke matrise ha klippet til å forlate av den siste av argumentene:

tgt="${!#}"
for src in "${@:1:$#-1}"; do
    cp "$src" "$tgt"
done
Svarte 23/09/2009 kl. 15:31
kilden bruker

stemmer
0

Du trenger ikke noen bash-spesifikke funksjoner:

eval siste = \ $ {$ #}
mens [$ # -gt 1]; gjøre
  echo "cp $ 1 $ siste"
  skifte
ferdig
Svarte 25/09/2009 kl. 16:26
kilden bruker

stemmer
0

Du kan gjøre dette direkte uten å skrive et skript ved hjelp xargs :

echo source1 source2 | tr "\n" "\0" | tr " " "\0" | 
   xargs --verbose -0 -I{} cp {} dest
Svarte 25/09/2009 kl. 19:58
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more