Linux中shell文件操作大全
2012-11-21 10:19:19
分类: 原文地址:Linux中shell文件操作大全 作者:fuliangcheng 1.创建文件夹 #!/bin/sh mkdir -m 777 "%%1" 2.创建文件 #!/bin/sh touch "%%1" 3.删除文件 #!/bin/sh rm -if "%%1" 4.删除文件夹 #!/bin/sh rm -rf "%%1" 5.删除一个目录下所有的文件夹 #!/bin/bash direc="%%1" #$(pwd) for dir2del in $direc/* ; do if [ -d $dir2del ]; then rm -rf $dir2del fi done 6.清空文件夹 #!/bin/bash direc="%%1" #$(pwd) rm -if $direc/* for dir2del in $direc/* ; do if [ -d $dir2del ]; then rm -rf $dir2del fi done 7.读取文件 #!/bin/sh 7.1.操作系统默认编码 cat "%%1" | while read line; do echo $line; done 7.2.UTF-8编码 cat "%%1" | while read line; do echo $line; done 7.3.分块读取 cat "%%1" | while read line; do echo $line; done 8.写入文件 #!/bin/sh cat > "%%1" << EOF %%2 EOF tee "%%1" > /dev/null << EOF %%2 EOF #sed -i '$a %%2' %%2 9.写入随机文件 #!/bin/sh cat > "%%1" << EOF %%2 EOF tee "%%1" > /dev/null << EOF %%2 EOF #sed -i '$a %%2' %%2 10.读取文件属性 #!/bin/bash file=%%1 file=${file:?'必须给出参数'} if [ ! -e $file ]; then echo "$file 不存在" exit 1 fi if [ -d $file ]; then echo "$file 是一个目录" if [ -x $file ]; then echo "可以" else echo "不可以" fi echo "对此进行搜索" elif [ -f $file ]; then echo "$file 是一个正规文件" else echo "$file不是一个正规文件" fi if [ -O $file ]; then echo "你是$file的拥有者" else echo "你不是$file的拥有者" fi if [ -r $file ]; then echo "你对$file拥有" else echo "你并不对$file拥有" fi echo "可读权限" if [ -w $file ]; then echo "你对$file拥有" else echo "你并不对$file拥有" fi echo "可写权限" if [ -x $file -a ! -d $file ]; then echo "你拥有对$file" else echo "你并不拥有对$file" fi echo "可执行的权限" 11.写入文件属性 #!/bin/bash #修改存放在ext2、ext3、ext4、xfs、ubifs、reiserfs、jfs等文件系统上的文件或目录属性,使用权限超级用户。 #一些功能是由Linux内核版本来支持的,如果Linux内核版本低于2.2,那么许多功能不能实现。同样-D检查压缩文件中的错误的功能,需要2.5.19以上内核才能支持。另外,通过chattr命令修改属性能够提高系统的安全性,但是它并不适合所有的目录。chattr命令不能保护/、/dev、/tmp、/var目录。 chattr [-RV] [-+=AacDdijsSu] [-v version] 文件或目录 -R:递归处理所有的文件及子目录。 -V:详细显示修改内容,并打印输出。 -:失效属性。 +:激活属性。 = :指定属性。 A:Atime,告诉系统不要修改对这个文件的最后访问时间。 S:Sync,一旦应用程序对这个文件执行了写操作,使系统立刻把修改的结果写到磁盘。 a:Append Only,系统只允许在这个文件之后追加数据,不允许任何进程覆盖或截断这个文件。如果目录具有这个属性,系统将只允许在这个目录下建立和修改文件,而不允许删除任何文件。 i:Immutable,系统不允许对这个文件进行任何的修改。如果目录具有这个属性,那么任何的进程只能修改目录之下的文件,不允许建立和删除文件。 D:检查压缩文件中的错误。 d:No dump,在进行文件系统备份时,dump程序将忽略这个文件。 C:Compress,系统以透明的方式压缩这个文件。从这个文件读取时,返回的是解压之后的数据;而向这个文件中写入数据时,数据首先被压缩之后才写入磁盘。 S:Secure Delete,让系统在删除这个文件时,使用0填充文件所在的区域。 u:Undelete,当一个应用程序请求删除这个文件,系统会保留其数据块以便以后能够恢复删除这个文件。 12.枚举一个目录中的所有文件夹 #!/bin/bash OLDIFS=$IFS IFS=: for path in $( find "%%1" -type d -printf "%p$IFS") do #"$path" done IFS=$OLDIFS 13.复制文件夹 #!/bin/sh cp -rf "%%1" "%%2" 14.复制一个目录下所有的文件夹到另一个目录下 #!/bin/bash direc="%%1" #$(pwd) for dir2cp in $direc/* ; do if [ -d $dir2cp ]; then cp $dir2cp "%%2" fi done 15.移动文件夹 #!/bin/sh mv -rf "%%1" "%%2" 16.移动一个目录下所有的文件夹到另一个目录下 #!/bin/bash direc="%%1" #$(pwd) for dir2mv in $direc/* ; do if [ -d $dir2mv ]; then mv $dir2mv "%%2" fi done 17.以一个文件夹的框架在另一个目录下创建文件夹和空文件 #!/bin/bash direc="%%1" #$(pwd) OLDIFS=$IFS IFS=: for path in $( find $direc -type d -printf "%p$IFS") do mkdir -p "%%2/${path:${#direc}+1}" done IFS=$OLDIFS #cp -a "%%1" "%%2" 表达式 含义 ${#string} {#string} 1,取得字符串长度 string=abc12342341 //等号二边不要有空格 echo ${#string} //结果11 expr length $string //结果11 expr "$string" : ".*" //结果11 分号二边要有空格,这里的:根match的用法差不多2,字符串所在位置 expr index $string '123' //结果4 字符串对应的下标是从0开始的这个方法让我想起来了js的indexOf,各种语言对字符串的操作方法大方向都差不多,如果有语言基础的话,学习shell会很快的。 3,从字符串开头到子串的最大长度 expr match $string 'abc.*3' //结果9个人觉得这个函数的用处不大,为什么要从开头开始呢。 4,字符串截取 echo ${string:4} //2342341 从第4位开始截取后面所有字符串 echo ${string:3:3} //123 从第3位开始截取后面3位 echo ${string:3:6} //123423 从第3位开始截取后面6位 echo ${string: -4} //2341 :右边有空格 截取后4位 echo ${string:(-4)} //2341 同上 expr substr $string 3 3 //123 从第3位开始截取后面3位上面的方法让我想起了,php的substr函数,后面截取的规则是一样的。 5,匹配显示内容 //例3中也有match和这里的match不同,上面显示的是匹配字符的长度,而下面的是匹配的内容 expr match $string '\([a-c]*[0-9]*\)' //abc12342341 expr $string : '\([a-c]*[0-9]\)' //abc1 expr $string : '.*\([0-9][0-9][0-9]\)' //341 显示括号中匹配的内容这里括号的用法,是不是根其他的括号用法有相似之处呢, 6,截取不匹配的内容 echo ${string#a*3} //42341 从$string左边开始,去掉最短匹配子串 echo ${string#c*3} //abc12342341 这样什么也没有匹配到 echo ${string#*c1*3} //42341 从$string左边开始,去掉最短匹配子串 echo ${string##a*3} //41 从$string左边开始,去掉最长匹配子串 echo ${string%3*1} //abc12342 从$string右边开始,去掉最短匹配子串 echo ${string%%3*1} //abc12 从$string右边开始,去掉最长匹配子串这里要注意,必须从字符串的第一个字符开始,或者从最后一个开始, 7,匹配并且替换 echo ${string/23/bb} //abc1bb42341 替换一次 echo ${string//23/bb} //abc1bb4bb41 双斜杠替换所有匹配 echo ${string/#abc/bb} //bb12342341 #以什么开头来匹配,根php中的^有点像 echo ${string/%41/bb} //abc123423bb %以什么结尾来匹配,根php中的$有点像 #!/bin/bash direc=$(pwd) for file in "$(direc)/*" do if [ "${file##*.}" = "sh" ]; then xterm -e bash $file elif [ "${file##*.}" = "bin" ]; then xterm -e $file elif [ "${file##*.}" = "run" ]; then xterm -e $file elif [ "${file##*.}" = "bundle" ]; then xterm -e $file elif [ "${file##*.}" = "pl" ]; then xterm -e perl $file elif [ "${file##*.}" = "class" ]; then xterm -e java ${file%.*} elif [ "${file##*.}" = "rpm" ]; then xterm -e rpm -ivh $file elif [ "${file##*.}" = "rb" ]; then xterm -e ruby $file elif [ "${file##*.}" = "py" ]; then xterm -e python $file elif [ "${file##*.}" = "jar" ]; then xterm -e java -jar $file fi done OLDIFS=$IFS IFS=: for path in $( find $direc -type d -printf "%p$IFS") do for file in `ls $path` do if [ "${file##*.}" = "sh" ]; then xterm -e bash """"$path"/"$file"""" elif [ "${file##*.}" = "bin" ]; then xterm -e """"$path"/"$file"""" elif [ "${file##*.}" = "run" ]; then xterm -e """"$path"/"$file"""" elif [ "${file##*.}" = "bundle" ]; then xterm -e """"$path"/"$file"""" elif [ "${file##*.}" = "pl" ]; then xterm -e perl """"$path"/"$file"""" elif [ "${file##*.}" = "class" ]; then xterm -e java """"$path"/"${file%.*}"""" elif [ "${file##*.}" = "rpm" ]; then xterm -e rpm -ivh """"$path"/"$file"""" elif [ "${file##*.}" = "rb" ]; then xterm -e ruby """"$path"/"$file"""" elif [ "${file##*.}" = "py" ]; then xterm -e python """"$path"/"$file"""" elif [ "${file##*.}" = "jar" ]; then xterm -e java -jar """"$path"/"$file"""" fi done done IFS=$OLDIFS 18.复制文件 #!/bin/sh cp %%1 %%2 19.复制一个目录下所有的文件到另一个目录 #!/bin/bash direc="%%1" $(pwd) for file in "$direc/*" do cp "$file" "%%1" done 20.提取扩展名 #!/bin/sh %%2=${%%1##.} 21.提取文件名 #!/bin/sh %%2="$(basename %%1)" 22.提取文件路径 #!/bin/sh %%2="$(dirname %%1)" 23.替换扩展名 #!/bin/sh %%3="$(basename %%1)$%%2" 24.追加路径 #!/bin/sh %%3="$(dirname %%1)/$%%2" 25.移动文件 #!/bin/sh mv "%%1" "%%2" 26.移动一个目录下所有文件到另一个目录 #!/bin/bash direc="%%1" #$(pwd) OLDIFS=$IFS IFS=: for file in "$(direc)/*" do mv "$file" "%%1" done IFS=$OLDIFS 27.指定目录下搜索文件 #!/bin/sh find -name "%%1" 28.打开文件对话框 #!/bin/sh %%1="$(Xdialog --fselect '~/' 0 0 2>&1)" 29.文件分割 #!/bin/sh split -b 2k "%%1" while read f1 f2 f3 do echo $f1 >> f1 echo $f2 >> f2 echo $f3 >> f3 done #!/bin/bash linenum=`wc -l httperr8007.log| awk '{print $1}'` n1=1 file=1 while [ $n1 -lt $linenum ] do n2=`expr $n1 + 999` sed -n "${n1}, ${n2}p" httperr8007.log > file_$file.log n1=`expr $n2 + 1` file=`expr $file + 1` done 其中httperr8007.log为你想分割的大文件,file_$file.log 为分割后的文件,最后为file_1.log,file_2.log,file_3.log……,分割完后的每个文件只有1000行(参数可以自己设置) split 参数: -b :后面可接欲分割成的档案大小,可加单位,例如 b, k, m 等; -l :以行数来进行分割; #按每个文件1000行来分割除 split -l 1000 httperr8007.log httperr httpaa,httpab,httpac ........ #按照每个文件100K来分割 split -b 100k httperr8007.log http httpaa,httpab,httpac ........ #!/bin/bash if [ $# -ne 2 ]; then echo 'Usage: split file size(in bytes)' exit fi file=$1 size=$2 if [ ! -f $file ]; then echo "$file doesn't exist" exit fi #TODO: test if $size is a valid integer filesize=`/bin/ls -l $file | awk '{print $5}'` echo filesize: $filesize let pieces=$filesize/$size let remain=$filesize-$pieces*$size if [ $remain -gt 0 ]; then let pieces=$pieces+1 fi echo pieces: $pieces i=0 while [ $i -lt $pieces ]; do echo split: $file.$i: dd if=$file of=$file.$i bs=$size count=1 skip=$i let i=$i+1 done echo "#!/bin/bash" > merge echo "i=0" >> merge echo "while [ $i -lt $pieces ];" >> merge echo "do" >> merge echo " echo merge: $file.$i" >> merge echo " if [ ! -f $file.$i ]; then" >> merge echo " echo merge: $file.$i missed" >> merge echo " rm -f $file.merged" >> merge echo " exit" >> merge echo " fi" >> merge echo " dd if=$file.$i of=$file.merged bs=$size count=1 seek=$i" >> merge echo " let i=$i+1" >> merge echo "done" >> merge chmod u+x merge' 30.文件合并 #!/bin/sh cp "%%1"+"%%2" "%%3" exec 3 do echo $f1 $f2 >> join.txt done #!/bin/bash if [ $# -ne 2 ]; then echo 'Usage: split file size(in bytes)' exit fi file=$1 size=$2 if [ ! -f $file ]; then echo "$file doesn't exist" exit fi #TODO: test if $size is a valid integer filesize=`/bin/ls -l $file | awk '{print $5}'` echo filesize: $filesize let pieces=$filesize/$size let remain=$filesize-$pieces*$size if [ $remain -gt 0 ]; then let pieces=$pieces+1 fi echo pieces: $pieces i=0 while [ $i -lt $pieces ]; do echo split: $file.$i: dd if=$file of=$file.$i bs=$size count=1 skip=$i let i=$i+1 done echo "#!/bin/bash" > merge echo "i=0" >> merge echo "while [ $i -lt $pieces ];" >> merge echo "do" >> merge echo " echo merge: $file.$i" >> merge echo " if [ ! -f $file.$i ]; then" >> merge echo " echo merge: $file.$i missed" >> merge echo " rm -f $file.merged" >> merge echo " exit" >> merge echo " fi" >> merge echo " dd if=$file.$i of=$file.merged bs=$size count=1 seek=$i" >> merge echo " let i=$i+1" >> merge echo "done" >> merge chmod u+x merge' 31.文件简单加密 #!/bin/bash #make test && make strings && sudo make install shc -r -f %%1.sh #%%1.x #%%1.x.c 32.文件简单解密 #!/bin/bash #make test && make strings && sudo make install shc -r -f %%1.sh #%%1.x #%%1.x.c 33.读取ini文件属性 #!/bin/bash if [ "$%%3" = "" ];then sed -n "/\[$%%2\]/,/\[.*\]/{ /^\[.*\]/d /^[ ]*$/d s/;.*$// p }" $1 elif [ "$%%4" = "" ];then sed -n "/\[$%%2\]/,/\[.*\]/{ /^\[.*\]/d /^[ ]*$/d s/;.*$// s/^[ | ]*$%%3[ | ]*=[ | ]*\(.*\)[ | ]*/\1/p }" $1 else if [ "$%%4" = "#" ];then sed "/\[$%%2\]/,/\[.*\]/{ s/^[ | ]*$%%3[ | ]*=.*/ / }p" $1 > /tmp/sed$$ mv /tmp/sed$$ $1 else sed "/\[$2\]/,/\[.*\]/{ s/^[ | ]*$%%3[ | ]*=.*/$%%3=$%%4/ }p" $1 > /tmp/sed$$ mv /tmp/sed$$ $%%1 fi fi 34.合并一个文件下所有的文件 #!/bin/sh cat $(ls |grep -E '%%1\.') > %%1 #!/bin/bash OLDIFS=$IFS IFS=: for path in $( find %%1 -type d -printf "%p$IFS") do for file in $path/*.c $path/*.cpp do if [[ ! "$file" =~ \*.[A-Za-z]+ ]]; then #"$(path)/$(file)" fi done done IFS=$OLDIFS #!/bin/bash cat <<'EOF'> combine.c #include int main() { FILE *f1,*f2,*f3; f1=fopen("a1.txt","r"); f2=fopen("a2.txt","r"); f3=fopen("a3.txt","w"); int a,b; a=getw(f1); /*从a1.txt和a2.txt中分别取最小的数a和b*/ b=getw(f2); while(!feof(f1)&&!feof(f2)) /*两个文件都没结束时,执行循环、比较*/ { if(a<=b) { putw(a,f3); a=getw(f1); } else {putw(b,f3); b=getw(f2); } } if(feof(f1)) /*文件a1.txt结束时,把a2.txt中的数全部输入a3.txt*/ {putw(b,f3); while((b=getw(f2))!=EOF) putw(b,f3); } if(feof(f2)) /*同上*/ { putw(a,f3); while((a=getw(f1))!=EOF) putw(a,f3); } fclose(f1); fclose(f2); fclose(f3); printf("已完成!"); return 0; } EOF gcc -o combine combine.c if [ $? -eq 0 ]; then ./combine else echo 'Compile ERROR' fi 35.写入ini文件属性 #!/bin/bash if [ "$%%3" = "" ];then sed -n "/\[$%%2\]/,/\[.*\]/{ /^\[.*\]/d /^[ ]*$/d s/;.*$// p }" $1 elif [ "$%%4" = "" ];then sed -n "/\[$%%2\]/,/\[.*\]/{ /^\[.*\]/d /^[ ]*$/d s/;.*$// s/^[ | ]*$%%3[ | ]*=[ | ]*\(.*\)[ | ]*/\1/p }" $1 else if [ "$%%4" = "#" ];then sed "/\[$%%2\]/,/\[.*\]/{ s/^[ | ]*$%%3[ | ]*=.*/ / }p" $1 > /tmp/sed$$ mv /tmp/sed$$ $%%1 else sed "/\[$%%2\]/,/\[.*\]/{ s/^[ | ]*$%%3[ | ]*=.*/$%%3=$%%4/ }p" $1 > /tmp/sed$$ mv /tmp/sed$$ $%%1 fi fi 36.获得当前路径 #!/bin/sh %%1=$(pwd) 37.读取XML数据库 如何通过shell命令行读取xml文件中某个属性所对应的值? 例如: 我希望能够通过Unix shell命令对属性键的名称BuildVersion进行查询,返回的结果是5,如何实现呀? #!/bin/bash grep BuildVersion|sed 's/.*<.*>\([^<].*\)<.*>.*/\1/' 结果返回的是“BuildVersion”,而不是“5”,如果要查询BuildVersion自动返回数值5应当如何写? 应该没错的。试一下: echo " 目前需要从xml文件提取数据,想做一个xmlparser.sh xml 类似这样 希望输入 xmlparser.sh a.xml hostip可以返回192.168.0.1 #!/bin/sh if [ $# -ne 2 ];then echo "Usage: $0 exit 0 fi grep $2 $1|awk '{print $2}'|grep -o "[0-9.]*" 把 grep $2 $1|awk '{print $2}'|grep -o "[0-9.]*" 改成 grep $2 $1|awk '{print $2}'|grep -Eo "[0-9.]+" 楼上这个有问题,如果我要得到的是 中的sharename,那么,呵呵,就错了 我觉得应该先定位到第二个参数“$2”的位置,然后再提取“=”后面的内容 这里有个完整的实现: Parse Simple XML Files using Bash – Extract Name Value Pairs and Attributes http://www./2010/parse-simple-xml-files-using-bash-extract-name-value-pairs-and-attributes/ 不过需要安装xmllint. 设计到对多个xml文件进行element的读取和列表。有人做过么? 举个例子, 多个xml文件里面都有 |
|