Bash: 测试一个变量是否存在于另一个变量中?
Bash: test if a variable exists within another variable?
我有两个变量,都是已被脚本移动的文件名列表。
变量 1:
由较大变量的 'read' 循环生成。在任何给定时刻它只包含一个文件名。
var1 = pic1.jpg
var1 = pic2 duplicate.jpg
var1 = pic3(dup).jpg
var1 = pic4.jpg
var1 = subfolder/subfolder picture.png
如上所示,文件名可以包含空格,但并非总是如此。
变量 2:包含文件列表的字符串,每个文件名由 \n
换行符分隔。
var2 = pic1.jpg \n
pic2 duplicate.jpg \n
pic3(dup).jpg \n
pic4.jpg
我正在尝试测试是否可以在 var2:
中找到 var1 的内容
listcontains() {
for list_item in ; do
# Does $list_item exist in ?
if [[ "$list_item" =~ "" ]]; then
return 0
else
return "1"
fi
done
}
# Call function to see if var1 is in var2
if listcontains "$var1" "$var2"
then
# var1 is in var2; do stuff...
else
# Do different stuff...
fi
这个逻辑显然是错误的,或者语法是错误的,因为它总是returns目前不匹配:
does pic2 exist in pic2 duplicate.jpg
pic2.jpg
pic3(dup).jpg
pic3.jpg?
no
does pic3(dup).jpg exist in pic2 duplicate.jpg
pic2.jpg
pic3(dup).jpg
pic3.jpg?
no
我还在学习 bash,所以如果有人能帮助我,我将不胜感激。
=~
的右侧是正则表达式模式。左侧是要匹配的字符串。
你的论据倒退了。您也没有考虑 $list_item
中的任何正则表达式特殊字符,这会导致您的匹配失败。
您的 $list_item
条目是部分文件名还是完整文件名?如果它们是完整的文件名,那么使用 read
循环并对 $var2
中的每一行进行精确匹配可能会更容易,而不是这样(更好的办法是在 [=14] 中使用文件名的关联数组=] 使匹配更快)。
据说使用字符串作为文件名是个坏主意,因为这使得对它们做任何事情(尤其是如果它们可以 spaces/etc。)变得困难甚至不可能。
在这里,我将向您展示它在控制台中的工作原理,然后您可以将代码复制到 bash 脚本文件中。
Frederick@Frederick-PC ~
$ for ele in "${var1[@]}"; do echo $ele; done
abc
def
Frederick@Frederick-PC ~
$ echo "$var2"
abc
ghi
Frederick@Frederick-PC ~
$ IFS=$'\n' read -rd '' -a array <<< "$var2"
Frederick@Frederick-PC ~
$ for ele in "${array[@]}"; do echo $ele; done
abc
ghi
Frederick@Frederick-PC ~
$ for ele in "${var1[@]}"; \
> do
> if [[ ${array[*]} =~ $ele ]]
> then
> echo "var2 contains $ele"
> else
> echo "var2 does not contain $ele"
> fi
> done
var2 contains abc
var2 does not contain def
我有两个变量,都是已被脚本移动的文件名列表。
变量 1: 由较大变量的 'read' 循环生成。在任何给定时刻它只包含一个文件名。
var1 = pic1.jpg
var1 = pic2 duplicate.jpg
var1 = pic3(dup).jpg
var1 = pic4.jpg
var1 = subfolder/subfolder picture.png
如上所示,文件名可以包含空格,但并非总是如此。
变量 2:包含文件列表的字符串,每个文件名由 \n
换行符分隔。
var2 = pic1.jpg
\n
pic2 duplicate.jpg\n
pic3(dup).jpg\n
pic4.jpg
我正在尝试测试是否可以在 var2:
中找到 var1 的内容 listcontains() {
for list_item in ; do
# Does $list_item exist in ?
if [[ "$list_item" =~ "" ]]; then
return 0
else
return "1"
fi
done
}
# Call function to see if var1 is in var2
if listcontains "$var1" "$var2"
then
# var1 is in var2; do stuff...
else
# Do different stuff...
fi
这个逻辑显然是错误的,或者语法是错误的,因为它总是returns目前不匹配:
does pic2 exist in pic2 duplicate.jpg
pic2.jpg
pic3(dup).jpg
pic3.jpg?
no
does pic3(dup).jpg exist in pic2 duplicate.jpg
pic2.jpg
pic3(dup).jpg
pic3.jpg?
no
我还在学习 bash,所以如果有人能帮助我,我将不胜感激。
=~
的右侧是正则表达式模式。左侧是要匹配的字符串。
你的论据倒退了。您也没有考虑 $list_item
中的任何正则表达式特殊字符,这会导致您的匹配失败。
您的 $list_item
条目是部分文件名还是完整文件名?如果它们是完整的文件名,那么使用 read
循环并对 $var2
中的每一行进行精确匹配可能会更容易,而不是这样(更好的办法是在 [=14] 中使用文件名的关联数组=] 使匹配更快)。
据说使用字符串作为文件名是个坏主意,因为这使得对它们做任何事情(尤其是如果它们可以 spaces/etc。)变得困难甚至不可能。
在这里,我将向您展示它在控制台中的工作原理,然后您可以将代码复制到 bash 脚本文件中。
Frederick@Frederick-PC ~
$ for ele in "${var1[@]}"; do echo $ele; done
abc
def
Frederick@Frederick-PC ~
$ echo "$var2"
abc
ghi
Frederick@Frederick-PC ~
$ IFS=$'\n' read -rd '' -a array <<< "$var2"
Frederick@Frederick-PC ~
$ for ele in "${array[@]}"; do echo $ele; done
abc
ghi
Frederick@Frederick-PC ~
$ for ele in "${var1[@]}"; \
> do
> if [[ ${array[*]} =~ $ele ]]
> then
> echo "var2 contains $ele"
> else
> echo "var2 does not contain $ele"
> fi
> done
var2 contains abc
var2 does not contain def