我编写了以下代码来搜索当前工作目录中包含字母“f”的所有文件名。
for i in *
do
echo $i
if [ $i = "*f*" ]
then
echo "no"
else
echo "yes"
fi
done
对于该目录中存在的每个文件,无论它是否包含“f”,都会打印“yes”。请帮忙。
答案1
[ $i = "*f*" ]
将存储在变量中的文件名i
按空格分割成单独的单词,将每个单词解释为通配符模式,如果匹配则将其展开,然后将生成的单词列表解析为[ … ]
.为了避免这种繁琐的操作,而是使用文件名,在变量扩展两边加上双引号。
[ "$i" = "*f*" ]
测试变量中的文件名是否i
为三字符名称*f*
。如果您没有具有此名称的文件,则所有文件都会触发 else 分支,因此yes
会被打印。
在 ksh、bash 或 zsh 中,您可以使用双括号构造来测试字符串是否与通配符模式匹配。将模式中的通配符保留为不带引号的。
if [[ "$i" = *f* ]]; then …
在普通 sh 中,没有双括号语法。要测试字符串是否与模式匹配,可以使用case
构造。
case "$i" in
*f*) echo "no";;
*) echo "yes";;
esac
答案2
由于您只想显示f
其中包含字母的文件,因此您需要continue
内置的。例如
for f in *; do if [[ $f != *f* ]]; then continue; else printf '%s\n' "$f yes"; fi; done
如果您想显示所有文件及其对应文件yes
,或者no
您需要执行以下操作:
for f in *; do if [[ $f = *f* ]]; then printf '%s\n' "$f yes"; else printf '%s\n' "$f no"; fi; done
上面的方法也适用于目录。因此,如果您想排除目录,可以使用! -d $f
例如:
for f in *; do if [[ $f = *f* && ! -d $f ]]; then printf '%s\n' "$f yes"; else printf '%s\n' "$f no"; fi; done
答案3
test
(是“test”内置命令的同义词)命令[
不允许使用模式。
STRING1 = STRING2
True if the strings are equal.
所以它逐个字母地比较字符串并确保不存在文件*f*
yes
目录中的名称(因此,当名称不匹配时,反向匹配脚本会回显)。
代替test
-buitin 甚至/bin/test
你可以自由使用bash 关键字 [[
When the `==' and `!=' operators are used, the string to the right of
the operator is used as a pattern and pattern matching is performed.
When the `=~' operator is used, the string to the right of the operator
is matched as a regular expression.
接下来的两个都可以使用:
[[ "$i" == *f* ]]
[[ "$i" =~ f ]]
但是,如果您只想打印当前目录f
中名称中包含文件名的文件就echo
足够了:
echo *f*
答案4
这是迭代练习吗?如果没有,使用 find 可能会更容易
search=$(find /path/to/dir -type f -name *f*)
echo $search