我在 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 中的列表var1
看起来像是每行一个条目的文件grep
。 var2
是选项的输入“文件” -f
,var1
是要 grep 的“文件”。 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[@]}"