[root@db01 scripts]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@db01 scripts]# uname -r
3.10.0-862.el7.x86_64
首先创建测试环境:
touch "I AM OLDBOY ERIC".txt
touch a.txt
touch b.txt
touch c.txt
[root@db01 scripts]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 4 09:03 a.txt
-rw-r--r-- 1 root root 0 Aug 4 09:04 b.txt
-rw-r--r-- 1 root root 0 Aug 4 09:04 c.txt
-rw-r--r-- 1 root root 0 Aug 4 08:55 I AM OLDBOY ERIC.txt
然后用for循环遍历当前目录下的每个文件名。
shell文件内容和执行结果如下
[root@db01 scripts]# vim test.sh
#!/bin/bash
for name in $(ls *.txt)
do
echo $name
done
[root@db01 scripts]# sh test.sh
a.txt
b.txt
c.txt
I
AM
OLDBOY
ERIC.txt
首先,不难发现,在脚本中使用ls
命令,在一般情况下没什么,可以正常输出文件名;但是但文件名含有空格时,ls
命令却无法正确识别空格是文件名称中的分隔符还是分隔不同的文件名,它只会按照单词为单位进行拆分。
其次,如果文件名中含有*
号,根据通配符原则,*
会当作识别当前目录下所有文件。
即便我们给它加上引号,也无济于事“$(ls *.txt)”
。由于引号中的内容是一个整体,for循环只遍历一次,输出的结果也自然是一个整体。
[root@db01 scripts]# sh test.sh
a.txt b.txt c.txt I AM OLDBOY ERIC.txt
事实上,我们不需要对其加太多符合,因为ls
命令是给人看的,而不是给脚本解析的。
#!/bin/bash
for txt in *.txt
do
echo $txt
done
使用*
通配符就可以匹配所有txt
后缀的文件名。但这个脚本会出现一个问题,如果当前目录没有匹配的文件名,那么该怎么循环遍历呢?
所以我们要增加一个判断语句。判断如果不是文件,则跳过,继续循环下一个。
for i in *.txt;
do
[ -e "$i" ] || continue
echo "$i"
done