2012-04-04 16 views
9

Esta entrada parece ser alrededor del 80% de lo que quiero hacer, pero nada de lo que he llegado con está funcionando: bash: how to delete elements from an array based on a patternBash: Eliminar los elementos presentes en una matriz de otro

Tengo dos matrices:

@tapes_in_drives=(SP1026,SP0995,SP0434) 

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

Necesito una solución bash que pueda eliminar todas las entradas presentes en @tapes_in_drives de @tapes.

Estoy construyendo un script para automatizar la expulsión de cintas de una biblioteca de cintas según la fecha de vencimiento, etc.

yo probamos este:

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

pero no funciona, no hay nada remoto.

Gracias por cualquier ayuda que pueda proporcionar.

EDIT:

Aquí está el código que estoy usando, escribí esto en Perl en un principio, por lo tanto, las definiciones @Variable y yo estaba súper cansada cuando escribí esta pregunta.

código:

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

Resultados:

obtener la lista de cintas

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

cintas en las unidades:

SP1001 SP1038 SP0923 SP0926 SP0925

Lista Tape 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

Como se puede ver, el los nombres de cinta de tapes_in_drives no se eliminan de la matriz de cintas.

+0

¿Qué pasa con su solución? Lo intenté, corrigiendo los errores de sintaxis, por supuesto, y parece funcionar. – C2H5OH

+0

¿por qué está usando '@' al principio de los nombres de las variables? No creo que sea un tema legítimo para un nombre de variable. Buena suerte. – shellter

Respuesta

12

Como dijo un comentario, solo se trata de errores de sintaxis.

Del espacio delimite las entradas de la matriz, no utilice el @, y la función está bien para sus datos de ejemplo. Tenga en cuenta que elimina cualquier entrada que contenga una entrada en tapes_in_drives, no solo aquellas que coinciden exactamente con una entrada.

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 

Resultados:

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

$ 

EDIT para responder a la edición en la pregunta

Esta línea:

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

Y esta línea: 0

inicializa tapes y tapes)in_drives como cadenas, no como matrices. Debe agregar paréntesis alrededor del valor asignado para convertirlos en matrices o el bucle no funcionará. También puede soltar el export, no es necesario a menos que desee que los procesos engendrados por el script hereden esas variables de shell como variables de entorno.

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

¡Perfecto! ¡Esto resuelve mi problema! ¡Gracias! – user708516

4

Otra solución:

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 
Cuestiones relacionadas