2012-04-04 13 views
9

Dieser Eintrag etwa 80% der zu sein scheint, was ich tun will, aber nichts, was ich habe kommen mit arbeitet: bash: how to delete elements from an array based on a patternBash: Löschen von Elementen in einem Array aus einem anderen

Ich habe zwei Arrays:

@tapes_in_drives=(SP1026,SP0995,SP0434) 

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

Ich brauche eine Bash-Lösung, die alle Einträge in @tapes_in_drives von @ Tapes löschen kann.

ich ein Skript bin den Aufbau des Ausstoßes von Bändern aus einer Bandbibliothek auf das Ablaufdatum auf Basis zu automatisieren, usw.

Ich versuchte dies:

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

aber es funktioniert nicht, nichts ist entfernt.

Vielen Dank für Ihre Hilfe.

EDIT:

Hier ist der Code ich verwende, ich schrieb dies in Perl ursprünglich, damit die @variable Definitionen und ich war sehr müde, wenn ich diese Frage schrieb.

Code:

#!/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[@]} 

Ergebnisse:

Erste Bandliste

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

Tapes in Laufwerke:

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

Wie Sie sehen können, die Bandnamen von tapes_in_drives werden nicht aus dem Bandarray entfernt.

+0

Was mit Ihrer Lösung falsch ist? Ich habe es versucht, natürlich die Syntaxfehler behoben, und es scheint zu funktionieren. – C2H5OH

+0

Warum verwenden Sie '@' am Anfang der Variablennamen? Ich glaube nicht, dass das ein legitimes Zeichen für einen Variablennamen ist. Viel Glück. – shellter

Antwort

12

Wie ein Kommentar sagte, ist es nur Syntaxfehler.

Platzbegrenzt die Array-Einträge, verwenden Sie nicht die @, und die Funktion ist gut für Ihre Beispieldaten. Beachten Sie, dass damit alle Einträge entfernt werden, die einen Eintrag in tapes_in_drives enthalten, und nicht nur diejenigen, die genau mit einem Eintrag übereinstimmen.

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 

Ergebnisse:

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

$ 

EDIT zum Bearbeiten in der Frage

Diese Zeile reagieren:

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

und diese Zeile:

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}'` 

initialisieren tapes und tapes)in_drives als Strings, nicht Arrays. Sie müssen Klammern um den zugewiesenen Wert hinzufügen, damit sie zu Arrays werden, oder die Schleife funktioniert nicht. Sie können auch die export löschen, es ist nicht erforderlich, es sei denn, Sie möchten, dass vom Skript erzeugte Prozesse diese Shellvariablen als Umgebungsvariablen erben.

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

Perfekt! Dies löst mein Problem! Vielen Dank! – user708516

4

Eine andere Lösung:

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 
Verwandte Themen