shell--文件操作1
2015-09-08 20:43
603 查看
1.遍历目录,查找其中所有文件,并统计每个文件的行数
定义一个函数detect,这是为了可以递归往子目录中操作接着一个循环遍历`ls $1`的结果,$1是第一个输入参数,也即查找路径
在循环中,首先判断文件是否是目录文件,如果是,则递归进入里边,
否则用wc命令得到文件中行的数目,并用cut命令得到wc结果中的行数,最后把结果保存到/home/user/shell/reslt.txt里边就好啦。
最后调用下这个函数。
#!/bin/sh function detect(){ for file in `ls $1` do if [ -d $1"/"$file ] then detect $1"/"$file else wc -L $1"/"$file | cut -d' ' -f 1-2>> /home/user/shell/result.txt fi done } path="/home/user/" detect $path
wc命令
wc即wordcount,可以统计文件的相关信息。-l选项统计行数
-c统计字节数
-w统计字数,字由空格,换行等区分
-L,最长行的长度(字符个数,比如aaa长度为3)
因为它的输出是“num 文件名”的形式,比如
root@ubuntu:/home/user/shell# wc -l t.sh
15 t.sh
所以要得到15的话就要使用cut命令了
ls -l | wc -l 可以用来统计当前路径下文件总数
cut命令
-b以字节为单位分割,注意的是wc里边是没有-b选项的哦-c以字符为单位分割,感觉和-b差不多啊,每一个字符都是用一个字节来存储的,像'\t'这样的也是嘛
-d自定义分隔符,可以用空格,或者字符之类的
-f与-d合作,指定显示分割区域的哪一部分,分割部分的序号从1开始
a x dd bb x zz ccc x dd root@ubuntu:/home/user/shell# cut -d'x' -f2 ls dd zz dd root@ubuntu:/home/user/shell# cut -d'x' -f1,2 ls a x dd bb x zz ccc x dd
root@ubuntu:/home/user/shell# cut -d' ' -f1-3 ls a x dd bb x zz ccc x dd
-d后边紧跟' ',单引号里边填充自定义分隔符,上面实验了字符x和空格, -f后则跟数字,表示输出的区域
从里面可以发现,如果输出的区域是连续的两个区域,那么分割它们的分隔符在输出的时候也是会输出的哦!
如果想要让一个变量作为分割的输入,该怎么写呢?用echo命令
var="abc x ec x dd" echo $var | cut -d'x' -f1,2 输出为abc x ec
如果想把文件作为输入的话,在最后边加文件路径就可以啦!
root@ubuntu:/home/user/shell# cut -c 1-5 /home/user/shell/ls a x d bb x ccc x
2.读入文件遍历每一行
如下读入文件并遍历每一行,取每行的第一个数字,之后累加#!/bin/sh path="/home/user/shell/result.txt" sum=0 while read myline do num=`echo $myline |cut -d' ' -f1` echo $num sum=`expr $num + $sum` done < $path echo "sum is "$sum这是一种方式,即
while read line
do
done < file
如下方式都可以
cat file | while read line
do
done
很奇怪的是,上面这种方式运行上面这个脚本,最后输出的sum依然是0,不知道肿么回事,好奇怪哦!难道循环里边的突然都变成局部变量了?然后修改就没用啦?
3.把一个文件夹中的文件后缀名改为bat
改名用mv操作,mv操作可以用来改名或是移动文件#!/bin/sh path="/home/user/data" for file in `ls $path` do new_file=${file%.*}".bat" if [ ! -e $path"/"$new_file ] then mv $path"/"$file $path"/"$new_file fi tmp=$(date +%Y%m%d:%H%M%S) tmp2=`date +%Y` echo $tmp $tmp2 done
mv命令
mv [选项] 源文件或目录 目标文件或目录视mv命令中第二个参数类型的不同(是目标文件还是目标目录),mv命令将文件重命名或将其移至一个新的目录中。当第二个参数类型是文件时,mv命令完成文件重命名,此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。当第二个参数是已存在的目录名称时,源文件或目录参数可以有多个,mv命令将各参数指定的源文件均移至目标目录中。在跨文件系统移动文件时,mv先拷贝,再将原有文件删除,而链至该文件的链接也将丢失。
移动多个文件到一个目录的话:
mv srcfile1 srcfile2 ... dstdir
或者
mv -t dstdir srcfile1 srcfile2 ...
如下
root@ubuntu:/home/user/shell# ls d.sh ls result.txt t2.sh test2.sh t.sh root@ubuntu:/home/user/shell# mkdir dir root@ubuntu:/home/user/shell# mv t.sh t2.sh dir root@ubuntu:/home/user/shell# ls dir d.sh ls result.txt test2.sh root@ubuntu:/home/user/shell# ls dir t2.sh t.sh root@ubuntu:/home/user/shell# cd dir root@ubuntu:/home/user/shell/dir# ls ../ dir d.sh ls result.txt test2.sh root@ubuntu:/home/user/shell/dir# mv -t ../ t.sh t2.sh root@ubuntu:/home/user/shell/dir# ls root@ubuntu:/home/user/shell/dir# ls ../ dir d.sh ls result.txt t2.sh test2.sh t.sh root@ubuntu:/home/user/shell/dir#
截断命令
${file#*/}: 拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt${file##*/}: 拿掉最后一条/及其左边的字符串:my.file.txt
${file#*.}: 拿掉第一个.及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个.及其左边的字符串:txt
${file%/*}: 拿掉最后条/及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条/及其右边的字符串:(空值)
${file%.*}: 拿掉最后一个.及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个.及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
#是去掉左边, ##最后一个
%是去掉右边, %%第一个
注意写的顺序,*究竟是放在/左边还是右边是根据*和%来变化的,如果是*,那么截断左边的,所以放在左边,%截断右边的,所以放到右边
date命令
格式里边的+%Y...,+号后边紧跟%哦要不就出错了!上面例子就是年月日:时分秒4.输入一个文件名,判断在当前目录是否存在
#!/bin/sh filepath=$(pwd) echo $filepath echo "read a file name:" read name if [ -e $filepath"/"$name ] then echo "exist" else echo "not exist" fi
当前目录可以用pwd命令得到,$()可以得到命令的结果,
比如$(expr 1 + 2)
我看到过有一个写成 $(cd "$(dirname $0)" | pwd)的命令来获取当前目录,$0就是当前脚本文件名,但实际上运行的时候,比如我的是t.sh
运行时敲命令./t.sh
那么$0也就是./t.sh,所以$(dirname $0)也就是".",不就是当前目录嘛。那么cd还有什么意义呢?很奇怪啊
好吧,确实是有意义的,比如说我的shell文件放在/home/user/shell里边,
但我在/home/user里边执行这个shell文件
#!/bin/sh filepath=$(dirname $0) echo $filepath cd $(dirname $0) filepath2=$(pwd) echo $filepath2 pwd echo "read a file name:" read name if [ -e $filepath2"/"$name ] then echo "exist" else echo "not exist" fi
root@ubuntu:/home/user# ./shell/t.sh ./shell /home/user/shell /home/user/shell read a file name: t.sh exist
$0是./shell/t.sh,所以dirname $0也就是./shell,cd ./shell也就进入了shell目录啦。
注意"."是此时的当前目录,shell则是当前目录的子目录,所以也就是进入当前目录的shell子目录里边。
如果写成cd /shell,那么"/"代表的是根目录的!!
cd ..则是进入当前目录的父目录。
运行中海油一个很奇怪的问题是如果我把cd命令和pwd命令合起来写,结果cd命令就没有执行,很奇怪。
相关文章推荐
- linux shell 学习时遇到的一些问题([: 11: y: unexpected operator)
- Linux Shell编程(5):整数运算
- Linux Shell编程(4): 逻辑运算符、逻辑表达式详解
- Linux Shell编程(3):数组
- Linux Shell编程(2): for while
- Linux Shell编程(1): 条件语句
- (总结)统计Apache或Nginx访问日志里的独立IP访问数量的Shell
- shell数组
- 使用shell脚本调用mysql数据库存储过程,并设置定时任务
- WinExec, ShellExecute,CreateProcess 的其他注意事项
- Linux shell脚本的字符串截取
- Linux Shell笔记之函数
- shell编程--遍历目录下的文件
- Linux Shell中的数组及遍历
- linux shell 数组建立及使用技巧
- Linux的SHELL学习指南
- shell 截取字符串(转)
- shell中特殊变量$0 $1 $# $$ $! $?的涵义
- shell脚本中位置参数 $0 $1 .. $* $#的备忘
- Linux shell脚本的字符串截取