指令:ls、cat、du、rename、dirname、basename、sort、diff、seq、head、tail、tree、chmod、cut、paster、正则
一:统计文件大小,行数,字符数相关命令
统计文件行数、单词数和字符数
wc file #统计文件行数,单词数,字符数wc -l file #统计文件行数cat file | wc -l #将stdin作为输入wc -w file #统计文件单词数cat file | wc -wwc -c file #统计文件字符数cat file | wc -cwc file -L #打印最长行的长度ls -l | grep "^-" | wc -l #统计当前文件夹下的文件个数
ls -lR | grep "^-" | wc -l #递归统计当前文件夹下的文件个数(包含子目录里的)
ls -l | grep "^d" | wc -l #统计当前文件夹下目录的个数
ls -lR | grep "^d" | wc -l #递归统计当前文件夹下目录的个数(包含子目录里的)
迭代文件中的行,单词,字符
1、用子shell迭代行cat test.txt | ( while read line; do echo $line; done )2、迭代行再迭代每一行中的每个单词while read line;do for word in $line do if [[ $word == 'test' ]]; then echo $word; fi donedone < test.txt3、迭代一个单词中的每一个字符,$(#word)返回变量word的长度,使用特殊标记法 ${string:i:num} string为要迭代的字符串;i为每次迭代的第i个字符;num为从i开始往后取num个字符。for((i=0;i<${#word};i++))doecho ${word:i:1} ;done文件大小,操作
du file.txt #查看file.txt占用的磁盘空间,默认以字节作为单位du file1 file2 file3 ... #查看多个文件的大小du -a /data/test #查看/data/test目录下所有文件的大小du -h file.txt #以KB,MB,GB显示文件占用的磁盘数更容易阅读du -h /data/test #以KB,MB,GB递归显示目录占用的磁盘数更容易阅读du -s file.txt #参数-s表示只输出合计数据du -c file1 file2 ... #输出所有文件占用的磁盘数量,并在最后显示总数du -b file #打印以字节为单位的文件大小du -k file #打印以KB为单位的文件大小du -m file #打印以MB为单位的文件大小du -B BLOCK_SIZE file #打印以指定块为单位的文件大小,如:du -B 4 test.shdu --exclude "*.txt" /data/test #打印/data/test目录中处理.txt文件外的所有文件的大小du --exclude-from list.txt /data/test #打印/data/test目录总不在list.txt中列出的文件中的文件的大小du -ak /data/test | sort -nrk 1 | head -n 5 #打印/data/test目录中最大的5个文件和目录find . -type f -exec du -k {} \; | sort -nrk 1 | head #打印当前目录中最大的10个文件#判断文件是否存在
if [[ -s $file ]]; then echo "not empty"fi#判断文件大小
stat -c %s $filestat --printf='%s\n' $filewc -c $file rename '*.bak' '' *.bak #去掉所有bak后缀dirname ‘/home/lalor/a.txt' #获取路径名 :/home/lalor
basename ‘/home/lalor/a.txt' #获取文件名 :a.txt#把所有空格改成下划线
find path -type f -exec rename 's/ /_/g' {} \;#删除前3行
$cat a.txt | sed 1,3d
二:文件排序,对比,打印与权限相关命令
排序和去重:sort 与 uniq
sort test.txt test2.txt > sorted.txt #对一个或多个文件以行为单位按照ASCII码的顺序进行排序,再把排序结果从定向到sorted.txtsort test.txt test2.txt -o sorted.txt #同上cat sorted.txt | uniq > sort_uniq.txt #对已排序的文件找出不重复的行并重定向到sort_uniq.txt文件sort test.txt | uniq #排序并去重(重复的行中会保留一行)sort -u test.txt #同上sort -n test.txt #参数-n指定按数字进行排序sort -r test.txt #参数-r指定按逆序进行排序sort -M test.txt #参数-M指定按月份进行排序sort -m sorted1.txt sorted2.txt #合并两个排过序的文件,并且不需要对合并后的文件再进行排序sort -k 2 test.txt #参数 -k 指定根据第二个键(列)进行排序sort -nk 2,3 test.txt #?sort -nrk 1 test.txt #将test.txt文件按照第一列的的数字进行逆向排序sort -z test.txt | xargs -0 #终止符\0使得xargs命令的使用更加安全sort -bd test.txt #参数-b用户忽略文件中的前导空白字符,参数-d用户指明以字典序进行排序uniq -u test.txt #只显示唯一的行,(重复的行全部去掉,一行也不保留)sort test.txt | uniq -u #同上sort test.txt | uniq -c #排序后统计各行在test.txt文件中出现的次数sort test.txt | uniq -d #排序后找出test.txt文件中重复的行sort test.txt | uniq -s 2 -w 3 #使用醒目的字符作为对比的列,通过参数 -s 2 忽略了前2个字符,使用参数 -w 3 指定用于比较的最大字符数为3echo "ahebhaaa" | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq -c | tr -d '\n' #管道 sed 's/[^\n]/&\n/g' 为每个字符后面追加一个换行符;管道 sed '/^$/d' 删除最后多出的那个换行符;管道 sort 对每一行进行排序(前面这样做是要拆分成行,因为sort只能进行行排序);管道uniq -c 打印每一行的重复次数; 管道 tr -d '\n' 将输入中的空格和换行符删除。结果:4a1b1e2h----------------------------------------
#!/bin/bash#测试一个文件是否已经排序sort -C file ;if [ $? -eq 0 ]; thenecho Sorted;elseecho Unsorted;fi#要检查是否按数字进行排序 则使用sort -nC-----------------------------------------
打印文件行:cat
echo 'Text through stdin' | cat - file.txt #将输入文件的内容与标准输入拼接在一起cat -s filename #压缩filename文件中连续的多个空白行成单个cat filename | tr -s '\n' #输出移除空白行后的filename内容,tr将连续的多个'\n'字符压缩成单个'\n'逆序打印行:tactac file #逆序打印文件seq 5 | tac #输出:54321file test.txt #确定文件的类型、
文件类型统计信息
---------------------------------------#!/bin/bash#filename:test.sh#执行:./test.sh /data/testif [ $# -ne 1 ];then echo $0 basepath; echo fipath=$1declare -A statarray;while read line;do ftype=`file -b "$line"` let statarray["$ftype"]++;done< <(find $path -type f -print)echo ================ File types and counts ====================for ftype in "${!statarray[@]}";do echo $ftype : ${statarray["$ftype"]}done------------------------------------------对比文件差异与修补
diff test1.txt test2.txt #test2.txt相对于test1.txt文件多了哪些行少了哪些行。diff -u test1.txt test2.txt #参数-u用于生成一体化输出,可读性更好一点。以+号起始的表示新加入的行,以-号起始的表示删除的行。diff -u test1.txt test2.txt > test.patch #(1)将输出重定向到test.patch文件patch -p1 test1.txt < test.patch #(2)将修改应用于test1.txt文件,此时test1.txt和test2.txt文件的内容一模一样。patch -p1 test1.txt < test.patch #撤销修改,也可加个-R参数跳过询问打印文件
head file #打印文件前10行cat file | head #同上head -n 5 file #打印文件前5行head -n -6 file #打印除了最后6行之外的所有行seq 11 | head -n -5 #打印除了最后数字7到11这5行之外的所有行,即数字1到6seq 100 | head -n 5 #打印数字1到5这5行。而不打印数字6到100这95行tail file #打印文件最后10行cat file | tail #同上tail -f file #打印文件最后10行,并随着数据的增加时时保持更新tail -n 5 file #打印最后5行tail -n +(10+1) #打印出了前10行之外的所有行seq 100 | tail -n +6 #打印除了前5行之外的所有行即第6到第100行。6=N+1,所以N=5 列出文件ls -d */ #只列出当前目录下的所有目录ls -F | grep "/$" #同上ls -l | grep "^d" #列出当前目录下所有目录的详细信息打印目录
tree path #打印path的目录树tree path -P "*.php" #打印path目录树,只显示目录树中的php文件tree path -I "*.php" #打印path目录树,只显示目录树中的除PHP文件外的文件tree -h path #打印出文件和目录大小tree path -H http://localhost -o out.html #生成一个包含目录树输出的HTML文件文件与目录权限:
chmod u=rwx g=rw o=x filename #设文件权限,用户权限为rwx,用户组权限为rw,其他实体权限为x(u指user,即文件的拥有者;g指group,即文件拥有者所属的用户组;o指other,其他)chmod o+w filename #给其他用户增加文件的写权限chmod g-r filename #删除用户组对文件的读权限chmod a+x filename #给所有用户增加文件的执行权限(a指all,表示所有用户)chmod a-w filename #删除所有用户对文件的写权限chmod 755 filename #设置文件的权限为755(r--=4, -w-=2, --x=1;rw-=6,rwx=7,-wx=3,r-x=5),755分别对应user,group,other用户的权限。chmod a+t dir_name #设置粘滞位应用于dir_name目录。(粘滞位是一种应用于目录的权限类型,使得只有目录的所有者才能删除目录中的文件,即使是用户组和其他用户有足够的权限也不能执行删除操作)chmod 755 . -R #递归设置当前目录及子目录的权限为755chmod 755 "($pwd)" -R #同上chown user:group filename #设置文件属于用户user,属于用户组groupchown user.group filename #同上chown root:root filename #设置文件属于root用户,属于root用户组chmod user:group filename -R #以递归方式设置所有权chattr +i file #设置文件为不可修改sudo adduser username #增加用户
sudo deluser username #删除用户passwd #修改当前用户的密码sudo passwd username #修改用户密码:sudo chfn userid #修改用户资料sudo usermod -L username #禁用某个帐户sudo passwd -l username #禁用某个帐户sudo usermod -U username #启用某个帐户sudo passwd -u username #启用某个帐户sudo usermod -G admin -a username #增加用户到admin组
三:文件切分,合并与重命名相关命令
分割文件:split && csplit
split -b 10k test.txt #将test.txt文件分割为多个文件,每个文件大小为10k,分别以xaa、xab、xac...命名split -b 10k test.txt -d -a 3 #将test.txt文件分割为多个文件,每个文件大小为10k。参数-d表示以数字为后缀,-a 3 表示后缀长度为3,比如x009,x019,x029,x039...split -l 100 test.txt #参数-l 100 是指分割成多个文件每个文件包含100行split -b 10k test.txt -d -a 3 xst #功能与前面相同,但是分割后的文件命名以xst为前缀:xst009、xst019、xst029、xst039...除了k(KB),其他单位还有M(MB),G(GB),c(byte),w(word)等。
------------------------------------------------------假设有个文件test.txt:SERVER-1aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccccccSERVER-2dddddddddddddddddeeeeeeeeeeeeeeeeefffffffffffffffffSERVER-3gggggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiicsplit test.txt /SERVER/ -n 2 -s {*} -f server -b "%02d.log"
rm server00.log#/SERVER/ 表示要匹配的文本样式,包括从当前行(包含)到下一行包含“SERVER”的行(不包含)。#{*}表示匹配重复分割知道文件结尾。可用{整数}的形式来指定执行分割的次数# -s 使命令进入静默模式,不打印其他信息# -n 指定分割后的文件名后缀的数字个数,例如01,02,03等。# -f 指定分割后的文件名前缀,-f server 指定前缀为server# -b 指定后缀格式。-b "%02d.log"因为分割后的第一个文件没有任何内容,故删除。----------------------------------------------------文件名切分
------------------------------------#!/bin/bashfile="test.png" #对于文件名类似file="test.txt.png.log" 这种类型可使用贪婪模式 %% 或者 ## name=$(file%.*) #文件名切分 %操作符表示非贪婪的删除位于%右侧的通配符所匹配的字符串 贪婪模式:name=${file%%.*}ext=$(file#*.) #文件扩展名 #操作符表示非贪婪的删除位于#左侧的通配符所匹配的字符串 贪婪模式:ext=$(file##*.)echo $name,$ext #输出结果:test,png------------------------------------按列切分文件
cut命令:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
使用说明
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。主要参数
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。-c :以字符为单位进行分割。-d :自定义分隔符,默认为制表符。-f :与-d一起使用,指定显示哪个区域。-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的<br />范围之内,该字符将被写出;否则,该字符将被排除。cut -f 2,3 filename #显示文件第2列和第3列
cut -f 2,3,7 filename #显示文件第2列和第3列和第7列grep "Invalid user" /var/log/auth.log | cut -d ' ' -f 10 #获取/var/log/auth.log 中包含“Invalid user”的行,并按照空格拆分行(-d ' ' 参数)获取第10个字符串(-f 10 参数)
按列合并文件
paste file1 file2 file3 ...paste test1.txt test2.txt #将test1.txt的每一列与test2.txt的每一列依次拼接起来。paste test1.txt test2.txt -d "," #参数-d明确指定定界符为逗号
批量重命名文件和移动
-------------------------------------#!/bin/bash#批量重命名图片文件count=1;for img in *.jpg *.png #依次取所有的jpg和png文件(.jpg可以改成 .[Jj][Pp][Gg] 从而匹配不区分大小写)donew=image-$count.${img##*.}mv "$img" "$new" 2> /dev/null # 2> 将mv命令的标准错误(stderr)重定向到/dev/null.防止错误信息打印到终端if [$? -eq 0]; # $?用于检查退出状态,即最近执行的命令没有错误,$?的值为0.否则$?为非0thenecho "Renaming $img to $new"let count++fidone--------------------------------------rename *.JPG *.jpg #建*.JPG 更名为*.jpgrename 's/ /_/ge' * #将文件名中的空格替换成字符"_";rename 'y/A-Z/a-z/' * #转换文件名为小写rename 'y/a-z/A-Z/' * #转换文件名为大写find . -type f -exec rename 's/ /_/ge' {} \; #将所有文件名中的空格替换为字符"_";for i in `ls`;do mv $i abc_$i;done #当前目录下所有文件都加上“abc_”前缀
for i in `ls`;do mv $i $(sed -r 's/abc_(.*)/\1/' <<< $i);done #当前目录下所有文件都去掉“abc_"前缀
四、shell正则表达式
匹配中文字符的正则表达式:[u4e00-u9fa5]
匹配双字节字符(包括汉字在内):[^x00-xff]匹配空白行的正则表达式:^ *$匹配HTML标记的正则表达式:<(S*?)[^>]*>.*?</1>|<.*? />匹配首尾空白字符的正则表达式:^s*|s*$匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*匹配网址URL的正则表达式:[a-zA-z]+://[^s]*匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$匹配国内电话号码:d{3}-d{8}|d{4}-d{7}匹配腾讯QQ号:[1-9][0-9]{4,}匹配中国邮政编码:[1-9]d{5}(?!d)匹配身份证:d{15}|d{18}匹配ip地址:d+.d+.d+.d+匹配特定数字: ^[1-9]d*$ #匹配正整数 ^-[1-9]d*$ #匹配负整数 ^-?[1-9]d*$ #匹配整数 ^[1-9]d*|0$ #匹配非负整数(正整数+ 0) ^-[1-9]d*|0$ #匹配非正整数(负整数+ 0) ^[1-9]d*.d*|0.d*[1-9]d*$ #匹配正浮点数 ^-([1-9]d*.d*|0.d*[1-9]d*)$ #匹配负浮点数 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$ #匹配浮点数 ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$ #匹配非负浮点数(正浮点数+ 0) ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$ #匹配非正浮点数(负浮点数+ 0) 匹配特定字符串: ^[A-Za-z]+$ #匹配由26个英文字母组成的字符串 ^[A-Z]+$ #匹配由26个英文字母的大写组成的字符串 ^[a-z]+$ #匹配由26个英文字母的小写组成的字符串 ^[A-Za-z0-9]+$ #匹配由数字和26个英文字母组成的字符串 ^w+$ #匹配由数字、26个英文字母或者下划线组成的字符串