14

このエントリは私がやりたいことの約80%のようですが、私が思いついたものは何も機能していません: bash:パターンに基づいて配列から要素を削除する方法

私は2つの配列を持っています:

@tapes_in_drives=(SP1026,SP0995,SP0434)

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

@tapes_in_drivesに存在するすべてのエントリを@tapesから削除できるbashソリューションが必要です。

有効期限などに基づいて、テープライブラリからのテープの取り出しを自動化するスクリプトを作成しています。

私はこれを試しました:

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

しかし、それは機能せず、何も削除されません。

あなたが提供できるどんな助けにも感謝します。

編集:

これが私が使用しているコードです。これは元々Perlで書いたので、@ variableの定義であり、この質問を書いたときはとても疲れていました。

コード:

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

結果:

テープリストの取得

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 SP1015 SP0777 SP0786 SP0788 SP0792 SP0907 SP0910 SP0923 SP0925 SP0926 SP0940 SP0963 SP0981 SP0986 SP0989 SP0994 SP0999 SP1007 SP1020 SP1021 SP1027 SP1039

ドライブ内のテープ:

SP1001 SP1038 SP0923 SP0926 SP0925

テープリスト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 SP1015 SP0777 SP0786 SP0788 SP0792 SP0907 SP0910 SP0923 SP0925 SP0926 SP0940 SP0963 SP0981 SP0986 SP0989 SP0994 SP0999 SP1007 SP1020 SP1021 SP1027 SP1039

ご覧のとおり、tapes_in_drivesのテープ名はtapes配列から削除されていません。

4

3 に答える 3

17

コメントが言ったように、それは単なる構文エラーです。

配列エントリをスペースで区切ります。を使用しない@でください。この関数は、サンプルデータに適しています。tapes_in_drivesエントリと完全に一致するエントリだけでなく、のエントリを含むすべてのエントリが削除されることに注意してください。

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

結果:

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

$

質問の編集に応答するための編集

この行:

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

そしてこの行:

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

配列ではなく、文字列として初期化tapesします。tapes)in_drives割り当てられている値を配列にするために括弧を追加する必要があります。そうしないと、ループが機能しません。を削除することもできexportます。スクリプトによって生成されたプロセスがそれらのシェル変数を環境変数として継承する必要がない限り、これは必要ありません。

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}'`)
于 2012-04-04T22:53:03.653 に答える
6

別の解決策:

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
于 2012-04-05T09:27:29.150 に答える
-1

この答えから盗まれ、あなたの変数に適応しました:

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

free_tapes=( $(printf "%s\n" "${tapes[@]}" "${tapes_in_drives[@]}" | sort | uniq -u) )

echo "${free_tapes[@]}"

出力:

SP0001 SP0002 SP2000 SP3000

一意の行のみを印刷する」-uように切り替えると、両方のアレイにあるテープは除外されます。uniq

于 2019-07-24T14:25:40.477 に答える