shell 实例之文件操作

实例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

猜你喜欢

转载自blog.csdn.net/xingxinmanong/article/details/77036919