( 参考自 linux shell 脚本攻略)
no=100
echo "ibase=2;obase=10;$no" | bc
a=1;b=2
let c=a+b
c=$[ a + b ]
c=$(( a + b ))
4.重定向
标准输入0,标准输出1,标准错误2
4.1 stdin 1
先清空再写入, > 等同于 1>
echo "This is a sample text 1" > temp.txt
追加, >> 等同于 1>>
echo "This is a sample text 1" >> temp.txt
4.2 stderr 0 stdout 2
当一个命令发生错误并退回时,会返回一个非零的退出状态;
而成功完成后,他会返回数字0.
退出状态可以从特殊变量$?中获得
将错误重定向到out.txt
ls + 2> out.txt
单独分别重定向
cmd 2>stderr.txt 1>stdout.txt
stderr 转换成 stdout, stderr和stdout都被定向到了同一个文件中
cmd 2>&1 output.txt
cmd &1 output.txt
执行时丢弃错误
cat a* 2> /dev/null
善用tee
追加(-a)写入stdin文件并stdout stderr
cat a* | tee -a out.txt | cat -n
5 重定向2
数组有两种:1. 普通数组,只能用数字作为索引。 2. 关联数组,可以使用字符串
#普通数组
[clz@localhost ~]$ array_var=(1,2,3,4,5,6)
[clz@localhost ~]$ array_var[0]='test1'
[clz@localhost ~]$ echo ${array_var[0]}
test1
[clz@localhost ~]$ echo ${array_var[@]}
test1
# 关联数组
[clz@localhost ~]$ declare -A ass_array
[clz@localhost ~]$ ass_array=([index1]='val1' [index]='val2')
## 值
[clz@localhost ~]$ echo ${ass_array[@]}
val1 val2
## 索引
[clz@localhost ~]$ echo ${!ass_array[@]}
index1 index
alias命令只是暂时起作用,一旦关闭当前终端便失效, 可以将它放入bashrc中
echo 'alias "cp $@ ~/backup; rm $@"' >> ~/.bashrc
\conmand # 转义,使得alias失效
# 日期
[clz@localhost ~]$ date
Wed Nov 11 19:02:31 PST 2015
#原子钟
[clz@localhost ~]$ date +%s
1447297366
# 提取信息
[clz@localhost ~]$ date --date "Jan 20 2001" +%A
Saturday
#输出想要的格式
[clz@localhost ~]$ date "+%d %B %Y"
11 November 2015
## 延时
sleep
#! /bin/bash
#Filename: sleep.sh
echo -n Count:
tput sc # 记录光标位置
Count=0;
while true;
do
if [[ $Count -lt 40 ]];
then let Count++;
sleep 1;
tput rc # 恢复光标位置
tput ed # 清除从当前光标位置到行尾之间的所有内用
echo -n $Count;
else exit 0;
fi
done
#!/bin/bash
#FileName:debug.sh
for i in {1..6}
do
set -x
echo $i
set +x
done
echo "Acript executed"
# result
[clz@localhost ~]$ ./debug.sh
+ echo 1
1
+ set +x
+ echo 2
2
+ set +x
+ echo 3
3
+ set +x
+ echo 4
4
+ set +x
+ echo 5
5
+ set +x
+ echo 6
6
+ set +x
# 快速设置调试
#!/bin/bashc-xv
#!/bin/bash
#Filename:func.sh
function fname()
{
echo $1, $2;
echo "$@";
echo "$*";
return 0;
}
fname 1 2
cmd_output=$(ls | cat -n)
#或者反引用
cmd_output=`ls | cat -n`
echo $cmd_output
pwd;
(cd /bin; ls);
pwd;
out="$(cat text.txt)"
out="$(cat text.txt)"
read -n 2 var
21
echo $var
21
line="root:x:0:0:root:/root:bin/bash";
oldIFS=$IFS;
IFS=":";
count=0;
for item in $line;
do
[ $count -eq 0 ] && user=$item;
[ $count -eq 6 ] && shell=$item;
let count++
done;
IFS=$oldIFS;
echo $user\'s shell is $shell;
if condition;
then
commands;
elif condition;
then
commands
else
commands
fi
# ifelse 嵌套
[ condition ] && action; #if true, action
[ condition ] || action; # if false, action
[ $var -ne 0 -a $var2 -gt 2 ] # 逻辑与
[ #vat -ne 0 -o $var2 -gt 2 ] # 逻辑或
[ -f $file_var ] # 包含文件名返回真
[ -x $var ] # 如果可执行返回真
#!/bin/bash
#Filename:fileexists.sh
fpath="/etc/passwd"
if [ -e $fpath ]
then
echo File exists
else
echo Dose not exist;
fi
使用字符串比较使用双中括号,因为有时候单个的中括号会产生错误、
=号前各有一个空格才是比较``
-s 压缩空白行
-T 制表符标记橙^|
-n 行号
find /home -name '8.txt' -print
find . \( -name "*.txt" -o -name "*.pdf" \) -print
# path 匹配文件和文件名
find /home/users -path "*slynux*" -print
# -regex 正则表达式匹配
find . iregex ".*\(\.py\|\.sh\)$"
# 匹配不以txt的文件名
find . ! -name "*.txt" -print
一些例子:
find . -regex ".*[winprice|processed|hashed]_.*_201511.*" -type f -exec rm -f {} \;
find . -maxdepth 1 -type f -print
注意顺序, 先深度后type效率高
find . -maxdepth 1 -atime +7 -print
find . -type f -size +2k # gt 2k
find . -type f -size 2k # qe 2k
# 找出没有执行权限的文件
find . -type f -name "*.php" ! -perm 644 -print
find . -typr f -user clz -print
#找到clz的文件并cat输入到文件中
find . -type f -user clz -exec cat {} \; >../all_clz_dils.txt
find . -type f -name "*.sh" -exec printf "Text file: %s\n" {} \;
-d 分割
-n 划分多行
cat args.txt | xargs -n 2 ./cecho.sh
arg1 arg2#
arg3#
cat args.txt | xargs -I {} ./cecho.sh -p {} -l
-p arg1 -l #
-p arg2 -l #
-p arg3 -l #
cat files.txt | ( while read arg; do cat $arg; done )
cat files.txt | xargs -I {} cat {}
cat text | tr '\t' ' '
echo "Hello 123 world 456" | tr -d '0-9'
Hello world
删除除了数字外的字符
echo hello 1 char 2 next 4 | tr -d -c '0-9 \n'
1 2 4
echo 'GNU is not UNNNNIX' | tr -s ' N'
GNU is not UNIX
# 生成MD5
[clz@localhost shell_learn]$ md5sum *.sh
55dfc48e7248ec2d88abe82b155a1725 cecho.sh
97e3c6038257978fb9bde47a97104beb debug.sh
335e04f8d5cdda182304840c35e30ee1 digui.sh
342e36c8d6203dda904f34a76d09e95d fileexists.sh
2b1cad931b74465c3c29628f8e8270e4 func.sh
62ab033ac0ab10bae684e006a570be35 IFSread.sh
9b6da33a9d92bcc27ad436f8bcfef7e1 sleep.sh
bd984f8245d30781ea00ee8e6984b8b1 success_test.sh
[clz@localhost shell_learn]$ md5sum *.sh > file_sum.md5
# 校验
[clz@localhost shell_learn]$ md5sum -c file_sum.md5
cecho.sh: OK
debug.sh: OK
digui.sh: OK
fileexists.sh: OK
func.sh: OK
IFSread.sh: OK
sleep.sh: OK
success_test.sh: OK
-n 数字 -r 逆序 -M 月份
-C 是否已经排序
-nC 是否按照数字排序
找出已排序文件中不重复的行
cat files | uniq > uniq_lines.txt
合并两个排过序的文件
sort -m sorted1 sorted2
[clz@localhost shell_learn]$ cat data.txt
1 mac 2000
3 winxp 4000
2 bsd 1000
# 按照第一列逆序排序
[clz@localhost shell_learn]$ sort -nrk 1 data.txt
3 winxp 4000
2 bsd 1000
1 mac 2000
# 按照第二列排序
[clz@localhost shell_learn]$ sort -k 2 data.txt
2 bsd 1000
1 mac 2000
3 winxp 4000
-u 只显示未出现重复得到行
-c 统计各行在文件中出现的次数
-d 重复行
-s 调过前n个字符
-w 指定用于比较的最大字符数
[clz@localhost shell_learn]$ sort data.txt
d:04:linux
u:01:bash
u:01:gnu
u:01:hack
[clz@localhost shell_learn]$ sort -r data.txt | uniq -s 2 -w 2
u:01:hack
d:04:linux
在用xargs命令输入的时候,最好为输出的各行添加一个0值字节终止符。
[clz@localhost shell_learn]$ uniq -z data.txt | xargs -0
u:01:gnu
d:04:linux
u:01:bash
u:01:hack
[clz@localhost shell_learn]$ uniq -z data.txt | xargs
xargs: WARNING: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
u:01:gnu d:04:linux u:01:bash u:01:hack
-b 文本块大小分割
-d 新文件用数字命名
-a 文件名长度
-l 根据行数分割
split -b 10k data.file -d -a 4
%操作符 取出文件名, 删除%右侧的(最短)通配符;
%% 最长匹配删除
[clz@localhost shell_learn]$ file_jpg="sample.jpg"
[clz@localhost shell_learn]$ name=${file_jpg%.*}
[clz@localhost shell_learn]$ echo File name is : $name
File name is : sample
取出后缀
[clz@localhost shell_learn]$ extension=${file_jpg#*.}
[clz@localhost shell_learn]$ echo Extension is: $extension
Extension is: jpg
‘#’删除前面的
‘##’删除最长的
该脚本将当前目录下文件重命名
#!/bin/bash
#Filename:rename.sh
#rename file
#set -x
count=1;
for img in *.[tT][xX][tT]
do
new=image-$count.${img##*.}
mv "$img" "$new" 2> /dev/null
if [ $? -eq 0 ]
then
echo "rename $img to $new"
let count++
else
echo "error"
fi
done