您的位置:首页 > 运维架构 > Shell

Linux中shell文件操作大全

2016-06-15 14:32 471 查看
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<f1

 exec 4<f2

 while read f1 <&3 && read f2 <&4

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文件中某个属性所对应的值?

例如:

BuildVersion 5

我希望能够通过Unix shell命令对属性键的名称BuildVersion进行查询,返回的结果是5,如何实现呀?

#!/bin/bash

grep BuildVersion|sed 's/.*<.*>\([^<].*\)<.*>.*/\1/'

结果返回的是“BuildVersion”,而不是“5”,如果要查询BuildVersion自动返回数值5应当如何写?

应该没错的。试一下: echo "BuildVersion 5"|grep BuildVersion|sed 's/.*<.*>\([^<].*\)<.*>.*/\1/'我在SL的终端里试,返回值是5

目前需要从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.humbug.in/2010/parse-simple-xml-files-using-bash-extract-name-value-pairs-and-attributes/
不过需要安装xmllint.

设计到对多个xml文件进行element的读取和列表。有人做过么?

举个例子,

多个xml文件里面都有
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: