只记录一些不太熟悉且强大的命令:
0
:到行首;$
:到行尾;v
:矩形区块选择;u
:撤销;r
:redo;.
:重复上个指令y
是复制,d
是删除,有一些通用变种:
yy
是一行,数字+yy
是几行,y1G
是从头到光标位置,yG
是到结尾,y0
是到行首,y$
是到行尾。:1,$s/word1/word2/gc
,从头到尾替换word1为word2,c
是可选的,在替换前请求确认。:w [filename]
:另存为, 甚至还有:n1,n2 w [filename]
。:sp [filename]
:分屏打开另一个文件。[ctrl] +w+↑
用来切换窗口。:set nu
:显示行号。:! ls /usr
:暂时离开vim去执行别的命令。本节的shell都以bash为例说明。
[ctrl]+u
:从当前位置删到开头,+k
则是删到结尾;[ctrl]+s
:暂停屏幕输出,+q
恢复屏幕输出。这些都可以通过stty
命令来查看修改。alias
可以给命令起别名,对复杂且常用的命令很好用history
是历史命令,不过条数有限。另外也建议不要给同一个用户开多个连接,因为历史记录会被覆盖乱掉。printf
可以在命令行上格式化打印数据,和C语言很像。diff file1 file2
可以查看两个文件的差异,在行的级别上;还可以比较目录。
diff
,我们可以制作补丁文件,diff -Naur old_file new_file > file.patch
patch
命令,可以将旧文件更新成新文件。cmp
会找字节级别上的差异。./program
alias
中的命令cd
$PATH
的目录中提供的脚本程序。;
是多条指令连续执行;&&
是前一条成功了,后面一条执行;否则不执行。||
恰好反过来,前一条失败了,后面一条执行,否则不执行。env
观察所有环境变量,set
观察所有环境变量+自定义变量,echo
观察一个变量。$
,但对其修改时则不用,修改时只需var=/home/user
即可。
PATH=${PATH}:/usr/local/bin
,不需要任何符号,直接把变量放上去就行了。read
命令,read -p "input sth." var
export
可以将自定义变量share给子进程,但也只有子进程可以看到。declare -i/a var
。参数-x
可以将var
设为当前shell的环境变量,如下条。$(locate find)
括起来或者用``包裹起来。$?
,一般成功则为0。/etc/profile
:整个系统的环境变量,在这个脚本中,还会额外读入并执行:/etc/profile.d/*.sh
:一些基本环境和alias/etc/locale.conf
:语系设置/usr/share/bash-completion-completions
:自动补齐规则~/.bash_profile
:用户的环境变量,如果没有的话就依次找~/.bash_login
或者~/.profile
。会额外读入:~/.bashrc
:一些个人设置,没登录的时候也会激活。source
或者.
命令可以主动激活一个配置文件~/.bash_logout
:注销shell时的操作。shell的命令中有四种通配符可以用:
*
:任意多个任意字符?
:一个任意字符[abcd]
:方括号中的一个字符。类似正则表达式,[0-9]
,[^a-c]
的用法也支持。通配符由shell负责解析,正则表达式则由命令本身负责解析。能支持正则表达式的命令则不再使用通配符规则,比如grep
,sed
,awk
等。
^
代表行首,$
代表行尾;.
和通配符中的?
含义一致;*
用来表示前一个字符零个或任意多个;\{n\}
表示n个前一个字符,\{n,m\}
表示[n,m]个前一个字符,\{n,\}
表示大于等于n个前一个字符。+
表示一个或多个前一个字符,?
表示0个或1个前一个字符。|
表示或。()
可以把部分正则表达式括号成一个群组,比如:
g(oo|la)d
表示两个单词之一,A(xyz)+c
表示中间一个或多个xyz。一些常用的正则表达式搭配:
.*
代表0个或任意多个任意字符;^$
:空白行还有一些宏可以用在正则表达式里:
[:space:]
表示任何空白符,[:blank:]
表示空格和TAB[:lower:],[:upper:]
表示小写/大写英文字母,[:alpha:]
代表所有英文字母[:digit:]
代表所有数字,[:alnum:]
代表字母和数字命令执行(可能)有三条数据流,输入数据流stdin,标准输出流stdout,标准错误输出流stderr,分别对应代码0,1,2。数据流重定向是将数据的末端从屏幕变成文件。
>
:将标准输出流输出到文件中(覆盖写),>>
则是追加写;2>, 2>>
是写标准错误流;2>&1 >, 2>&1 >>
是同时把输出流和错误列写出来;/dev/null
这个黑洞中去;<
是从文件中获取输入(而非命令行),<<
是指定用户键盘输入的结束字符串(没啥用)。tee
:转存命令,可以在多个管道命令传递数据之间额外保存中间结果到文件中,参数-a
表示追加写。管道命令|
是将前一个命令的标准输出作为后一个命令的标准输入,这要求后一个命令必须能接受标准输入,即是管道命令。
grep
选行: last | grep 'root'
:将输入中带有pattern的行留下来,pattern支持正则表达式。参数-c
可以计数,-i
忽略大小写,-v
反向选择,-n
显示行号,-A 3
显示后几行,-B 4
显示前几行。
grep
有一个重要功能就是搜索文件中出现了什么关键字,比如grep 'key' ./*
, grep 'key' $(find . -type f)
, find . -type f | xargs -n 10 grep 'key'
cut
选列: echo $PATH | cut -d ":" -f 5,7
:将输入的每一行,按照-d
后面的字符split,然后取出第-f
个元素。有一个参数-c
可以直接选择字符的索引区间,比如export | cut -c 10-20
sort
排序:默认按照字典序排序各行。参数-f
忽略大小写,-b
忽略前导空格,-r
反向排序,-n
数值排序。
less data.txt | sort -t ":" -k 3-5 -n
,用:
split,按照第3-5列数值排序。uniq
去重:-i
忽略大小写,-c
对每个元素进行计数。tr
,join
等命令可以对数据做删除/替换,两组数据的join,笛卡尔积join等,不详细展开。wc
计数:-l
统计行数,-w
统计英文字母数,-m
统计字符数。split
划分:-b
参数确定分割后的最大文件大小,-l
确定最大行数。
split -l 10 file new_files
:由于这里需要一个文件参数,如果在管道中就用-
来代替文件名代表从标准输入中获得,输出的文件也可以用-
来代替代表标准输出流。xargs
将标准输入流变成参数:很多常用命令并非管道命令,比如ls
,我们可以通过...|xargs ls
把标准输入流变成参数传给ls
命令。
...|xargs -n 1 ls
表示每次只传递一个参数;另外-p
表示每次执行都询问,-e
可以设置最后一个参数是什么样的。sed
:强大的数据操作工具。
...|sed '2,5d'
表示删除【2,5】行;...|sed '2,$d'
表示删到结尾。...|sed '2a new line'
表示在第二行下面新插入一行,文字为new line;通过\+回车
还可以直接插入多行;...|sed '2,5c repleaced text'
,把[2,5]行替换成了一行replaced text;...|sed -n '2,5p'
,很简答,只打印[2,5]行,注意参数-n
表示只显示操作的部分;...|grep 'sth'| sed 's/old word'/new word/g
,注意old word可以是一个正则表达式。-i
可以直接修改文件中的数据。-e
,如果需要多个连续操作,每个操作前面都需要加-e
awk
: 表格式数据处理工具。以换行符定义行,以空格或[tab]分割列(可以设置分割符)。awk会迭代处理每一行,$1
代表第一列,依次类推,然后判断条件,满足则执行操作。$0
最特殊,表示一整行。awk '条件1{操作1} 条件2{操作2}'
... | awk '{print $1 "\t" $3}'
无条件,打印第一列和第三列的数据;awk命令还藏了两个变量,NR
表示现在处理的是第几行,NF
表示该行共有几列。
... | awk '{print "cur line:" NR ", total columns: " NF}'
设置分隔符是另一个变量FS
... | awk 'BEGIN {FS=":"} $3<10{print $3}'
:第一个操作设置分隔符为:
,随后若第三列<10,则打印第三列。BEGIN表示从第一行的分隔符就是:
,否则从第二行开始。在awk的操作中,即{}中,可以有多条命令,用;
或者回车可以分隔;甚至还可以定义变量,且无需加上$
读取变量;再甚至可以有条件逻辑和循环逻辑,非常强大
ulimit
ulimit
可以对各个用户对系统的资源使用作出限制,比如:
-d
是对一个进程的内存大小的限制(不仅仅是二进制文件的数据段,也包括动态申请的堆)。-l
最大锁住的内存,即钉死在内存里,不允许交换的内存数据。shell脚本就是一系列shell命令写到文件里,从上到下依次执行而已。
规则是碰到回车就执行当前行命令,除非是用\+回车
换行。
基本规则:
#!/bin/bash
用来指明这个脚本在哪个shell中执行,=。注意这不是注释,没有这一行系统不知道用哪个shell来执行这个脚本。exit + 数字
来结束这个脚本。执行方式:
$PATH
里面,或者用sh
或bash
显示执行,其实都会启用一个子进程,在子进程中执行,执行结束后,定义的变量也就丢弃了;source
来执行,这样是直接在父进程中执行,定义的变量也会得到保留。-x
会打印执行过的每一条命令,可以用于调试。脚本的参数:脚本也可以拥有参数,在脚本中以特殊方式读取
$1
代表第一个参数,后续的依次类推;$0
代表脚本路径;$@
代表全部参数的一个变量条件逻辑:
if [some condition] && [other condition]; then
sth
elif [conditon1] || [condition2]; then
sth
else [condition 3]
sth
fi
选择逻辑:
case $var in
"one")
sth
;;
"two")
sth
;;
*)
echo "Usage: ./$0 one or two"
;;
esac
循环逻辑:
while [condition]
do
sth
done
until [condition]
do
sth
done
for var in one two three
do
sth
done
for var in $(ls .), for var in {1..100}, for var in $(seq 1 100)
for (( i=1; i<=${th}; i=i+1 ))
do
sth
done
shell内的函数:没有返回值,但是可以像命令那样传递些参数进来,里面仍然会有$1
,$2
,$0
是函数名,但与整个脚本的不同,只看调用的时候提供的参数。
function fname(){
echo "$1"
}
fname hello