bash + var2でvar2で定義された文字列を削除する方法

bash + var2でvar2で定義された文字列を削除する方法

Bashスクリプトで次の変数を使用しています - val1、val2

val1は、オペレーティングシステムLinuxに存在する必要があるすべてのディスクを表します。

val2 はオペレーティングシステム Linux の現在のディスクを表します。

私の目標は、「$ val1」変数から「$ val2」ディスクを削除することです。

val1="sdb sdc sdd sde sdf sdg sdh sdi sdj sdk"
val2="sdb sdc sdf sdd sde sdg"

予想される結果:

val3=sdh sdi sdj sdk

そして、次のようにval3の結果を設定します。

答え1

そしてsed置換:

val3=$(sed -E 's/\<('"$(tr ' ' '|' <<<"$val2")"')\> *//g' <<<"$val1")
echo "$val3"
sdh sdi sdj sdk

  • $(tr ' ' '|' <<<"$val2")- 正規表現交代グループを模倣して、sdb|sdc|sdf|sdd|sde|sdg全体の構造は次のようになります。\<(sdb|sdc|sdf|sdd|sde|sdg)\>
  • \<\>- 単語の境界。

答え2

一方通行:

$ val1="sdb sdc sdd sde sdf sdg sdh sdi sdj sdk"
$ val2="sdb sdc sdf sdd sde sdg"
$ comm -23 <(echo "$val1" | sed "s/ /\n/g" | sort) <(echo "$val2" | sed "s/ /\n/g"| sort) | paste -sd" "
sdh sdi sdj sdk
$

echo "$val1" | sed "s/ /\n/g" | sort : 変数リストの平面化と並べ替え
comm -23: 平面化された val1 のインポート 固有のコンテンツ
paste -sd" ": 結果を連結するにはスペースを使用します。

答え3

注文する


echo $val1| tr " " "\n" > val1.txt; echo $val2| tr " " "\n"  > val2.txt; val3=`awk 'NR==FNR {a[$1];next}!($1 in a) {print $1}' val2.txt val1.txt` ;echo $val3

出力

 echo $val3
sdh sdi sdj sdk

答え4

そしてgrepプロセスの交換:

#!/bin/bash

val1='sdb sdc sdd sde sdf sdg sdh sdi sdj sdk'
val2='sdb sdc sdf sdd sde sdg'

val3="$(grep -v -F -f <(printf "%s\n" $val2) <(printf "%s\n" $val1) | xargs)"

echo "$val1"
echo "$val2"
echo "$val3"

手続き型置換は、printf "%s\n"リストとvar2をvar11行に1つのエントリを持つファイルのように見せるために使用されますgrepvar2オプションの入力「ファイル」-fvar1grepの「ファイル」です。 xargs複数行の出力をスペースで区切られた単一の文字列に変換するのは怠惰ですが、grep便利なトリックです。

配列も同様です。

#!/bin/bash

val1=(sdb sdc sdd sde sdf sdg sdh sdi sdj sdk)
val2=(sdb sdc sdf sdd sde sdg)

val3=($(grep -vFf <(printf "%s\n" "${val2[@]}") <(printf "%s\n" "${val1[@]}")))

echo "${val1[@]}"
echo "${val2[@]}"
echo "${val3[@]}"

関連情報