实例1 - 遍历所有文件
#!/bin/bash
# 创建文件
if [ ! -d testdir ]; then
mkdir testdir
fi
cd testdir
if [ ! -f test.lua.bak.2017 ]; then
touch test.lua.bak.2017
fi
if [ ! -d subdir ]; then
mkdir subdir
cd subdir
touch init.lua
cd ..
fi
cd ..
# 遍历所有文件
searchFile()
{
echo now in $1
for file in $1/*
do
if test -f $file; then
echo $file
elif test -d $file; then
searchFile $file
fi
done
}
searchFile ./testdir
执行结果
now in ./testdir
now in ./testdir/subdir
./testdir/subdir/init.lua
./testdir/test.lua.bak.2017
这个脚本所做的工作,首先在脚本所在的目录下创建一个子目录 testdir,然后在 testdir 下新建一个文件 test.lua.bak.2017 和一个子目录 subdir,再在 subdir 下创建一个文件 init.lua。创建完文件后,切换回脚本所在目录,遍历 testdir 下面的所有文件。
函数 searchFile 接收一个参数,表示要遍历的文件夹,首次调用时传 ./testdir 进去,表示从 ./testdir 这个目录开始遍历。然后遍历 $1/* 就可以得到当前遍历目录下的所有文件或子目录,使用 -f 测试是否为普通文件,使用 -d 测试是否为目录。如果是普通文件,直接输出文件的路径,如果是目录,则递归调用 searchFile。
实例2 - 取文件名和后缀名
#!/bin/bash
# 创建文件
if [ ! -d testdir ]; then
mkdir testdir
fi
cd testdir
if [ ! -f test.lua.bak.2017 ]; then
touch test.lua.bak.2017
fi
if [ ! -d subdir ]; then
mkdir subdir
cd subdir
touch init.lua
cd ..
fi
cd ..
# 取文件名和后缀名
getName()
{
fullname=$1
fullname=${fullname##*/}
filename=${fullname%.*}
extname=${fullname##*.}
echo full name: $fullname
echo filename: $filename
echo extenname: $extname
}
# 遍历所有文件
searchFile()
{
echo now in $1
for file in $1/*
do
if test -f $file; then
getName $file
elif test -d $file; then
searchFile $file
fi
done
}
searchFile ./testdir
扩展上面的脚本,添加一个取文件的文件名和后缀名的函数。在这个函数里,使用 % 和 # 来分割字符串。
- % 是右适配符,从右向左开始适配,然后把适配到的内容删掉。取文件的文件名,需要把文件后缀名和 . 去掉,所以适配符应该写 .*,这样就能匹配到 .后缀名 并将其删掉。
- # 是左适配符,从左向右开始适配,然后把适配到的内容删掉。取文件的后缀名,需要把文件名和 . 去年,所以适配符应该写 *.,这样就能匹配到 文件名. 并将其删掉。
- % 和 # 是非贪婪操作符,找到第一个适配的字符串就停止查找。而 %% 和 ## 是贪婪操作符,找到最后一个适配的字符串才停止查找。
举个例子,对文件 name=test.lua.bak.2017
,
${name%.*}=test.lua.bak
,因为匹配 .2017 后就停止查找了,删掉 .2017 后就得到结果 test.lua.bak。
${name%%.*}=test
,因为得匹配到 .lua.bak.2017 才停止查找,删掉 .lua.bak.2017 就得到结果 test。
${name#*.}=lua.bak.2017
,因为匹配到 test. 后就停止查找了,删掉 test. 后就得到结果 lua.bak.2017。
${name##*.}=2017
,因为得匹配到 test.lua.bak. 才停止查找,删掉 test.lua.bak. 后就得到结果 2017。
一般文件的后缀名都是最后的 .ext,所以取文件名使用非贪婪的 %,取后缀名使用贪婪的 ##。
脚本执行结果
now in ./testdir
now in ./testdir/subdir
full name: init.lua
filename: init
extenname: lua
full name: test.lua.bak.2017
filename: test.lua.bak
extenname: 2017
实例3 - 批量文件操作
需求:找到 ./src 目录下的所有 lua 文件,将其后缀名以为 .c 并保存在 ./out 目录下,要保持原来的目录结构。
#!/bin/bash
if [ ! -d src ]; then
echo "src 目录不存在!"
exit 1
fi
if [ -d out ]; then
rm -r out
fi
mkdir out
function search()
{
for sub in $1/*
do
if [ -f $sub ]; then
if [[ ${sub##*.} = lua ]]; then
local dest=${sub/src/out}
dest=${dest/.lua/.c}
echo copy $sub to $dest
cp $sub $dest
fi
elif [ -d $sub ]; then
newdir=${sub/src/out}
mkdir $newdir
search $sub
fi
done
}
search ./src