Shell札记

来自linux中国网wiki
Evan讨论 | 贡献2021年10月29日 (五) 08:05的版本 →‎R
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

note

6.替换字符串, tr from to 
eg:
	find . -name "*.wma" | replace ".wma" ".lrc" | xargs rm -f
	查找当前目录下的所有后缀为".wma"的,并把后缀名替换为".lrc"
	这样可以删除同名的文件但格式不同,如想删除音乐我那个的文件
	删除时,希望既删除音乐文件,又删除歌词
7.shell的变量赋值等号两边不能有空格

8.文件操作
	4.执行命令或的错误流和标准输出重定向
	ls + 2>stderr.txt 1>stdout.txt
	若该命令发生错误,则把错误信息写入stderr.txt中
	正确时,写入stdout.txt中
	5.可把错误流输出和标准输出指向同一个文件
	ls + 2>&1 output.txt
	or
	ls + &>output.txt
	6.当有错误信息不想显示时,可以把错误信息重定向到/dev/null设备中
	该设备是一个特殊的设备,接受所有的输入,然后自动的消失所有的
	内容,这个设备也叫做字符垃圾桶或块设备洞
	ls + 2> /dev/null
		
	#on my way 		
	file >/dev/null 2>&1

     7.当想查看信息,但遇到错误信息时,不记录下来,可以用tee
		tee 从标准输入stdin输入到指定的文件
		eg:
			cat a* | tee out.txt | cat -n
			这里将cat查看的以a开头的文件的内容通过管道(|)标准输入
			到out.txt中,在读出来,并显示行号
	# on my way 		
        ./lnmp  2>&1 | tee 36nmp.log
        
 9.获取终端信息
 10.日期
	date	获取当地时间
	date +%s	获取时间戳
	1、将日期字符串转换为时间戳
		date --date "2013年 07月 30日 星期二 10:40:48 CST" +%s
		->1375186380
	2.通过给定日期,获取星期几
		date --date "Jan 20 2001" +%A
		->星期六
		Weekday %a (for example:. Sat)
			%A (for example: Saturday)
		Month
			%b (for example: Nov)
			%B (for example: November)
		Day 	%d (for example: 31)
		Date 	in format (mm/dd/yy) 
			%D (for example: 10/18/10)
		Year 	%y (for example: 10)
			%Y (for example: 2010)
		Hour 	%I or %H (for example: 08)
		Minute 	%M (for example: 33)
		Second 	%S (for example: 10)
		Nano second %N (for example:695208515)
		epoch UNIX time in seconds %s (for example: 1290049486)
11.$? 读取命令返回值

12.()创建子进程
	(cd /home/zhang; ls)
	执行不影响主进程
13.加上双引号可以输出\n

14.read命令
	read -n num var 读入num个字符进入变量var,不用按回车去确认
		echo $var 打印出字符var
	read -s var 像读入密码一样,不显示输入字符
		echo $var 打印出字符var
    read -p "Enter input: " var 输出提示消息并接收变量输入
	read -t 2 var 2秒后执行输入
	read -d ":" var		设定输入指定字符结束输入

#on my way 
echo -e "\033[31m  Please input U domain! Default domain: a.com!!! \033[0m"
#read -p  "\033[31m Please input U domain! Default domain: a.com \033[0m" domain
read domain

	
15.使用IFS(Internal Field Separator) 分割字符串
	例子1:~/workspace/shell/seperate-setentce.sh
		csv格式读取每个人信息
	例子2:-/workspace/readFile.sh 
		读入/etc/passwd,并格式化输出
	data="name,sex,rollno,location"
#To read each of the item in a variable, we can use IFS.
	oldIFS=$IFS
	IFS=,	#now,
	for item in $data;
	do
		echo Item: $item
	done
	IFS=$oldIFS
	The output is as follows:
	Item: name
	Item: sex
	Item: rollno
	Item: location
	
16.循环
	1. for循环
		for var in list;
		do 
            		          commands
		done
		list 可以是字符串string,或者是序列
		eg:
			for i in {a..z};
			do
				echo $i
			done
			这将打印a到z的所有字母
		也可以用跟c语言一样的格式
		for(i=0;i < 10; i++){
			commands
		}
	2.While 循环
		while condition
		do
			commands
		done
		无限循环用 true
	3.until循环
		直到条件满足时推出
		x=0
		until [ $x -eq 9];
		do 
               		let x++
			echo $x
		done
		当x等于9时结束循环
17.条件语句
	if condition;
	then
		commands
	fi
	or
	if condition;
	then
		commands
	else if condition;
	then 
		commands
	else
		commands
	fi
	可以使用如下代替:
		[ condition ] && action 如果condition 是true 执行action
		[ condition ] || action 如果condition 是false执行action
	注:在[]与condition两边有空格
	
18.数学比较
	1. 表达式 [ $var -eq 0]
	-eq		相等
	-ne		不等
	-gt		greate than 大于
	-ge		greate than or equal to 大于等于
	-le		less than or equal to 小于等于
    2.
		AND 可以写作 -a
		OR	可以写作 -o
		eg:
			[ $var -ne 0 -a $var2 -gt 2 ]
					
	3.文件判断
		[ -f $file_var ]: Returns true if the given variable holds a regular filepath or
		  filename.
		[ -x $var ]: Returns true if the given variable holds a file path or filename which
		    is executable.
		[ -d $var ]: Returns true if the given variable holds a directory path or directory
			  name.
		[ -e $var ]: Returns true if the given variable holds an existing file.
		[ -c $var ]: Returns true if the given variable holds path of a character device file.
		[ -b $var ]: Returns true if the given variable holds path of a block device file.
		[ -w $var ]: Returns true if the given variable holds path of a file which is writable.
		[ -r $var ]: Returns true if the given variable holds path of a file which is
			    readable.
		[ -L $var ]: Returns true if the given variable holds path of a symlink.
        eg;
			fpath="/etc/passwd"
			if [ -e $fpath ]; then
			echo File exists;
			else
			echo Does not exist;
			fi
	4.字符串比较
		使用两个[[]]
		如:
			[[ $str1 == $str2 ]]
			[[ $str1 != $str2 ]]
			[[ $str1 > $str2 ]]
			[[ $str1 < $str2 ]]
			[[ -z $str2 ]]	如果为空返回true
			[[ -n $str2 ]]	如果不为空返回true
		注:等号后有空格表示比较,没有空格表示赋值
	5.test命令
		if [ $var -eq 0 ]; then echo "True"; fi
		can be written as
		if test $var -eq 0 ; then echo "True"; fi
		
19.常用的命令
	1.cat使用
		1.读取文件内容和把多个文件连接在一起
			cat file1 file2
		2.从标准输入中读入数据
			echo 'text through stdin' | cat - file
			注:'-'代表标准输入的文件名
			这里是把echo输入的文档(stdin)和file连接在一起输出
		3.cat -s file
			这里将多行的空行只替换为一行,这样易于阅读
			cat file | tr -s '\n'
			-s是压缩的意思,这里是将多个连续的字符'\n'压缩为一个
		4.cat -T file 
			可以查看文件中饿tab键,有会被用'^I'显示,尤其用于
			对python调试很重要
		5.cat -n file
			显示文件,标注行号
	2.script/scriptreplay使用
		1.script -t 2>timing.log -a output.seesion
			开启命令记录,timing.log 记录时间,
			output.session记录输出内容
			当出错时,重定向到timing.log
	3,find的使用
		find的参数非常多,他的参数之间是与的关系,所以在
		写命令时,应该考虑参数的先后顺序
		如:
			find . -mindepth 2 -type f 
			和
			find . -type f -mindepth 2
			第一个先直接到下面两层目录下搜索
			第二个先搜索所有的文件,然后判断是否是下面第二层
			这显然会浪费时间
		1.find的命令用于查找文件
			find path -name	'filename'	查找匹配filename的文件
		2. -iname
			不区分大小写
		3.使用或可以查询多个满足条件的文件
			find . \( -name '*.txt' -o -name '*.pdf' \) -print
			使用括号是使之作为一个单一的单元
		4.使用-path可以找到匹配的路径
			find . -path '*test*' -print
			可以找到下面是test的文件或test的文件夹
		5.使用正则表达式匹配
			find . -regex ".*\(\.py\|\.sh\)$"
			查找在当前文件下,以.py或.sh结尾的任意文件
			.*代表任意字符,零次或多次
		6.使用“!”符号,即非
			find . ! -name "*.txt" -print
			找出当前文件下的所有非.txt结尾的文件
		7.指定深度搜索文件
			find . -maxdepth 1 -type f -print
			查找当前(1级)的所有文件(file)
		8.指定类型查找文件
			一般文件	f	Reguler file
			软连接文件	l	Symbolic link
			目录		d	Directory
			字符设备	c	Character special device
			块设备		b	Block device
			socket		s	Socket
			fifo		p	FiFo
			find . -type f
			find . -type d 
			find . -type l
		9.通过时间进行搜索
			1.单位为:天
				修改时间	-atime
				访问时间	-mtime	这里是修改内容
				创建时间	-ctime	这里是修改属性也算
				用法: find -atime -(+)days 
				使用-号代表days以内,+号代表days 之外
				find . -type f -atime -7 -print
					查找7天以内的被访问的文件 
				find . -type f -atime +7 -print
					查找7天以外的被访问的文件 
			2.单位为:分钟
				-amin	
				-min
				-cmin 
				find . -type f -amin +7 -print
				在7分钟之前访问的文件
			3.使用-newer 选项,通过指定文件,来比较比当前文件
			的时间更靠近当前时间的文件
				find . -type f -newer file.txt -print
				查找当前文件夹下,所有的时间比file.txt新的文件
		10.通过指定大小来搜索
			-size 大小
			find . -type f -size +2k
			查找2k以上的文件
			find . -type f -size -2k
			查找2k以内的文件
			其中:	
				b	-512 byte blocks
				c	-bytes
				w	-two byte words
				k	-Kilobyte
				m	-Megabyte
				G	-Gigabyte
		11.查找的匹配的文件并删除
			find . -type f -name "*.swp" -delete
		12.通过权限来匹配文件
			find . -type f -name "*.php" ! -perm 644 -print
			查找当前文件夹下的,以.php结尾的并且权限不是644的文件
		13.通过所有者查询
			find . -type f -user zhang -print
		14.通过find命令来执行其他的动作,命令
			find . -type f -user root -exec chown zhang {} \;
			这里查找当前文件夹下的所有属于root的文件,更改其属主为zhang
			{} \是特定的意义,
			eng:
				find -exec command {} \
				Execute command; true if 0 status is  returned.   All
				following arguments to find are taken to be arguments
				to the command until an argument consisting of `;' is
				encountered.  The string `{}' is replaced by the cur‐
				rent file name being processed everywhere  it  occurs
				in  the  arguments  to the command, not just in argu‐
				ments where it is alone, as in some versions of find.
				Both  of these constructions might need to be escaped
				(with a `\') or quoted to protect them from expansion
				by  the shell. 
			译:执行命令,返回0代表正确状态,所有查找出来的文件作为变量以;结束,作为command
				的参数。'{}'作为替换查找出来的文件,做为参数传入command, '\'是转义变量里面
				的特殊字符
			find . -type f -name "*.c" -exec cat {} \; > all_c_files.txt
			将所有的.c文件写入all_c_files.txt
			find . -type f -name "*.sh" -exec printf "Shell file: %s\n" {} \;
			查找所有的shell文件,并打印出来,这里可以看{}变量的作用
			Shell file :
			 ./date.shShell file :
			 ./seperate-setentce.shShell file :
			 ./printf.shShell file :
			 ./array.shShell file :
		15.跳过指定的目录搜索
			find ~/workspace/ \(-name ".git" -prune \) -o \( -type f -print \)
			跳过.git目录,搜索其他文件
	4.xargs使用
		该命令主要用于重新格式化标准输入,需要用到管道
		command | xargs
		1.多行输入转换为单行
			cat > test.txt
			1 2 3     4 5
			6 7
			cat test.txt | xargs
			1 2 3 4 5 6 7
			注:1.将多行输入转换为单行输入
				2.将许多空格压缩为一个空格
		2.当行输入转换为多行
			cat > test.txt | xargs -n=3
			1 2 3
			4 5 6
			7
			注:每一行只有3个元素,以空格分开
		3.按指定字符分割字符串
			echo 'aaaubbuccu' | xargs -d u
			aaa bb cc
		4.指定每行的最大元素
			echo 'aaaubbuccudd' | xargs -d u -n 2
			aaa bb			
                        cc dd
			注:-n 指定最大一行有多少元素
		5.从指定的文件中读入参数
			cat > cecho.sh
			#! /bin/bash
			echo $*'#'
			cat > args.txt
			arg1
			arg2
			arg3
			cat args.txt | xargs -n 1 ./cecho.sh
			args1 #
			args2 #
			args3 #
			cat args.txt | xargs -n 3 ./cecho.sh
			arg1 arg2 arg3 #
		6.使用-I从文件中混插入参数
			cat args.txt | xargs -I {} ./cecho.sh -p {} 1
			-p args1 1#
			-p args2 1#
			-p args3 1#	
			注:使用-I 将{}取代每次读入的数据
		7.和find一起使用
			find . -type f -name "*.txt" -print | xargs rm -f
			这条命令会删除所有的以.txt结尾的文件,不过这个
			命令有危险,当文件名中有空格时,会被解析成两个文件
			这样,有可能将其他文件也删除了
			改正:
			find . -type f -name "*.txt" -print0 | xargs -0 rm -f
			这条命令,使用了-print0 会提示当有空格时应该添加'\0'字符
			这样就不会删错文件了
	5.tr的使用
		tr - translate or delete characters
		主要用于替换,删除,翻译字符
		只能接受标准输入,不能在命令行接受参数
		所以必须用到管道
		tr [options] set1 set2
		注:把set1的字符,映射到set2
			如果里set1的长度大于set2,则复制set2后面的字符
			来补充和set1的字符长度一样
			如果len(set1) < len(set2)则忽略掉set2的其余字符
		1.大小写转换
			echo "HELLO WHO IS THIS?" | tr 'A-Z' 'a-z'
			hello who is this?
			这里 'a-z'是一个连续的字符集合
			可以简单大构造集合如:
			'abcd-}', 'aA,', 'a-ce-x', 'a-c0-9\t\n'
			除前两个外,其余都含有他们之间的字符
		2.通过实现集合间的映射,加密文件
			echo 12345 | tr '0-9' '9876543210'
			87654
			echo 87654 | tr '9876543210' '0-9'
			12345
			注:这两个集合就像是密钥一样
			例子:ROT13算法,13个字符循环,可以用同一个密钥加密并解密
			输入原文得出密文:
			$ echo "tr came, tr saw, tr conquered." | tr
			'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
			'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
			将密文输入得出原文:
			$ echo ge pnzr, ge fnj, ge pbadhrerq. | tr
			'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
			'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
		3.通过实现替换,可以控制输出
			cat text | tr ' ' '\t'
			将以','分割的字符用'\t'替换
			如:
			cat /etc/passwd -n | tr ':' '\t'
			注:将文件/etc/passwd,以'\t'展示
		4.删除字符
			cat file.txt | tr -d set
			删除在集合set中的元素
			如:
				echo "Hello 123 world 456" | tr -d '0-9'
				Hello world
				这样可过滤掉所有的数字
		5.保留字符
			tr -c set
			如:
				echo hello 1 char 2 next 3 | tr -d -c '0-9 \n'
				1   2   3
				这里保留了数字,空格和换行符
		6.压缩字符串
			tr -s set
			属于set中的字符连续的只能出现一次		
			如:将多余的空格压缩为一个
			ehco "GNU is    not   UNIx ?" | tr -s ' '
			GNU is not UNIX?
			注:这里将多余的空格替换为单个空格
		7.做运算
			$ cat > sum.txt
			1
			2
			3
			4
			5
			$ cat sum.txt | echo $[ $(tr '\n' '+') 0]
			15
			注:将'\n'替换为'+',然后作为$[ 1 + 2 + 3 + 4 + 5 + 0 ],做和
		8.用特定的字符类替换
			常用的有:
				alnum: Alphanumeric characters 字母和数字
				alpha: Alphabetic characters	字母
				contrl: Control(non-printing) characters 控制字符,非打印字符
				digit: Numeric characters 数字
				graph: Graphic characters 
				lower: Lower-case alphabetic characters 小写字母
				print: Printable characters 可打印字符
				punct: Punctuation characters 标点符号
				space: Whitespace characters 空白字符
				upper: Upper-case characters 大写字符
				xdigit: Hexadecimal characters 十六进制字符
			用法:
				tr [:class:] [:class:]
			如:
				tr '[:lower:]' '[:upper:]'
     		
		
  

References

linux shell学习记录(一)