2012-04-04 15 views
9

Questa voce sembra essere circa l'80% di quello che voglio fare, ma niente che è venuta in mente sta lavorando: bash: how to delete elements from an array based on a patternBash: Eliminare gli elementi presenti in un array da un altro

Ho due matrici:

@tapes_in_drives=(SP1026,SP0995,SP0434) 

@tapes=(SP0001,SP0002,SP0434,SP0995,SP1026,SP2000,SP3000) 

Ho bisogno di una soluzione bash in grado di eliminare tutte le voci presenti in @tapes_in_drives da @tapes.

sto costruendo uno script per automatizzare l'espulsione di nastri da una libreria a nastro in base alla data di scadenza, ecc

ho provato questo:

for i in "${tapes_in_drives[@]}"; do 
     tapes=(${tapes[@]//*$i*}) 
done 

ma non funziona, non c'è nulla di rimosso.

Grazie per l'aiuto che puoi fornire.

EDIT:

Ecco il codice che sto utilizzando, ho scritto questo in Perl in origine, quindi le definizioni @variabile ed ero super stanco quando ho scritto questa domanda.

CODICE:

#!/usr/bin/bash 

# If media expires less than this many days, keep it 
export days_expired="30" 

# Set to 1 to get debug output to console 
export debug="1" 

# Get list of SPxxxxx tapes that are physically in the library 
if [ $debug -eq 1 ]; then echo "Getting tape list"; fi 
export tapes=`vmquery -rn 1 -b | tail +4 | awk '{print \$1}' && vmquery -rn 4 -b | tail +4 | awk '{print \$1}'` 

if [ $debug -eq 1 ]; then echo ${tapes[@]}; fi 

# Query tape drives for tapes 
export tapes_in_drives=`ssh srv-reg-nbms-01 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}' && ssh srv-reg-nbms-02 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}'` 

if [ $debug -eq 1 ]; then 
    echo "" 
    echo "Tapes in Drives:" 
    echo ${tapes_in_drives[@]} 
    echo ""; 
fi 


# Remove tapes in drives from list of tapes 
for i in "${tapes_in_drives[@]}"; do 
    tapes=(${tapes[@]//*$i*}) 
done 

echo "Tape List 2" 
echo ${tapes[@]} 

Risultati:

Ottenere lista nastro

SP0011 SP0039 SP0402 SP0434 SP0464 SP0516 SP0551 SP0600 SP0604 SP0726 SP0731 SP0765 SP0767 SP0779 SP0781 SP0787 SP0793 SP0794 SP0805 SP0828 SP0830 SP0832 SP0927 SP0928 SP0936 SP0983 SP0995 SP1001 SP1004 SP1008 SP1015 SP1017 SP1026 SP1033 SP1036 SP1038 SP0042 SP0049 SP0150 SP0462 SP0473 SP0517 SP0557 SP0560 SP0642 SP0659 SP0697 SP0712 SP0723 SP0766 SP0777 SP0786 SP0788 SP0792 SP0907 SP0910 SP0923 SP0925 SP0926 SP0940 SP0963 SP0981 SP0986 SP0989 SP0994 SP0999 SP1007 SP1020 SP1021 SP1027 SP1039

nastri nelle unità:

SP1001 SP1038 SP0923 SP0926 SP0925

Tape List 2

SP0011 SP0039 SP0402 SP0434 SP0464 SP0516 SP0551 SP0600 SP0604 SP0726 SP0731 SP0765 SP0767 SP0779 SP0781 SP0787 SP0793 SP0794 SP0805 SP0828 SP0830 SP0832 SP0927 SP0928 SP0936 SP0983 SP0995 SP1001 SP1004 SP1008 SP1015 SP1017 SP1026 SP1033 SP1036 SP1038 SP0042 SP0049 SP0150 SP0462 SP0473 SP0517 SP0557 SP0560 SP0642 SP0659 SP0697 SP0712 SP0723 SP0766 SP0777 SP0786 SP0788 SP0792 SP0907 SP0910 SP0923 SP0925 SP0926 SP0940 SP0963 SP0981 SP0986 SP0989 SP0994 SP0999 SP1007 SP1020 SP1021 SP1027 SP1039

Come si può vedere, la i nomi dei nastri da tapes_in_drives non vengono rimossi dall'array dei nastri.

+0

Cosa c'è di sbagliato con la soluzione? L'ho provato, correggendo gli errori di sintassi, ovviamente, e sembra funzionare. – C2H5OH

+0

perché stai usando '@' all'inizio dei nomi delle variabili? Non penso che sia un carattere legittimo per un nome variabile. In bocca al lupo. – shellter

risposta

12

Come un commento ha detto, sono solo errori di sintassi.

Spazio-delimitare le voci di matrice, non utilizzare il @ e la funzione va bene per i dati di esempio. Si noti che rimuove qualsiasi voce contenente una voce in tapes_in_drives, non solo quelli che corrispondono esattamente a una voce.

tapes=(SP0001 SP0002 SP0434 SP0995 SP1026 SP2000 SP3000) 
tapes_in_drives=(SP1026 SP0995 SP0434) 
for i in "${tapes_in_drives[@]}"; do 
     tapes=(${tapes[@]//*$i*}) 
done 

Risultati:

$ echo ${tapes[0]} 
SP0001 
$ echo ${tapes[1]} 
SP0002 
$ echo ${tapes[2]} 
SP2000 
$ echo ${tapes[3]} 
SP3000 
$ echo ${tapes[4]} 

$ 

EDIT per rispondere alla modifica in questione

Questa linea:

export tapes=`vmquery -rn 1 -b | tail +4 | awk '{print \$1}' && vmquery -rn 4 -b | tail +4 | awk '{print \$1}'` 

E questa linea:

export tapes_in_drives=`ssh srv-reg-nbms-01 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}' && ssh srv-reg-nbms-02 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}'` 

inizializza tapes e tapes)in_drives come stringhe, non in matrici. È necessario aggiungere parentesi attorno al valore assegnato per trasformarle in matrici, altrimenti il ​​ciclo non funzionerà. È inoltre possibile eliminare lo export, non è necessario a meno che non si desideri che i processi generati dallo script ereditino tali variabili di shell come variabili di ambiente.

tapes=(`vmquery -rn 1 -b | tail +4 | awk '{print \$1}' && vmquery -rn 4 -b | tail +4 | awk '{print \$1}'`) 

tapes_in_drives=(`ssh srv-reg-nbms-01 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}' && ssh srv-reg-nbms-02 "echo 's d q'|/usr/openv/volmgr/bin/tldtest -r /dev/smc0|grep 'Barcode'" | awk '{print $3}'`) 
+0

Perfetto! Questo risolve il mio problema! Grazie! – user708516

4

Un'altra soluzione:

tapes_in_drives=(SP1026 SP0995 SP0434) 
tapes=(SP0001 SP0002 SP0434 SP0995 SP1026 SP2000 SP3000) 

tps=" ${tapes[*]} "      # stringify the array 

for item in ${tapes_in_drives[@]}; do 
    tps=${tps/ ${item}/}    # replace item 
done 
tapes=($tps)       # replace the array 
Problemi correlati