!:n*表示上一条指令中的第n项参数开始到指令末尾的所有内容(n可以取0-9)。
!:n-与!:n*类似,但是前者不包含上一条指令的最后一个参数。
!*相当于!:1*,即上一条指令中的所有参数。
注意这边的参数是指没有经shell展开的那种,而是上一条指令原来敲进去的那些。
% ls a* a1 a2 a3 % rm !$!em:2*表示上一条以em开头的指令中的第2项参数开始到指令末尾的所有内容。
% co −l 1171 6830 2340 RCS/1171,v −> 1171 ... RCS/2340,v −> 2340 revision 1.8 (locked) done % vi !:2* vi 1171 6830 2340 3 files to edit ... % ci −m"Changed TERM xref." !* ci −m"Changed TERM xref." 1171 6830 2340^abc^xyz把上一条指令中的abc替换为xyz后执行,只替换一次。
^gg删除上一条指令中的gg,只删除一次。
!em:p输出上一个以em开头的指令内容,但不执行。
% !m:p more gobbledygook.c % ^k^k2 more gobbledygook2.c!!重复上一条指令
!:s/xy/yx将上一条指令中的xy替换为yx并执行。
!so重复上一条以so开头的指令
!?fn重复上一条包含fn的指令(fn可以在命令或参数名中出现)
!:0上一条指令中的命令名。
!:3上一条指令中的第三个参数。
!:2-4上一条指令中的第2个到第4个参数。
!:-3上一条指令开头到第三个参数。
!^上一条指令中的第一个参数。
!$上一条指令中的最后一个参数。
!?fn?%上一条包含fn的指令中第一个包含fn的词。
!?fn?^上一条包含fn的指令中的第一个参数。
!!:s/xx/ab/将上一条指令中的xx替换成ab并执行,替换一次,替换失败则报错。
!m:s/b/c/将上一条以m开头的指令中的b替换成c并执行,替换一次,替换失败则报错。
分隔符不一定要用 / 啦,也可以用 : 啥的。
!!:s/xy/&yx将上一条指令中的xy替换成xyyx并执行,这里 & 指代前面的匹配内容。
!!:gs/xy/yx/将上一条指令中所有的xy替换成yx并执行,这里 g 表示全局替换。而且g要写在s之前,不然会报错,囧。
!!:g&将上一条指令内容全局重复上一次替换,并执行。书里面说对于指令中的单个词中还是只替换一次,但是我在zsh下测试时单个词还是有多次替换,也许是zsh跟csh的处理有不同?
!-3执行历史记录中倒数第3条指令。
fc -l列出最近执行的指令。
fc –l 21列出序号从21开始的、以及其后所有最近执行的指令。
fc –l vi列出从最近一条以vi开头的指令开始的、以及其后所有最近执行的指令。
fc 21 23列出序号从21到23的所有最近执行的指令。
fc v e列出从最近一条以v开头的指令开始的、到其后最近一条以e开头的指令结束的,以及二者间所有最近执行的指令。
12. Job Control
在进行作业控制之前,必须预先决定将该作业置于前台还是后台执行。
当一个程序在前台执行时,如果没有被预先重定向键盘输入,这些键盘输入内容就会作为该程序的标准输入。因此,在该程序执行完毕之前,前台无法执行其他指令,也就是前台每次只能执行一个程序。
当一个程序在后台执行时,该程序并不与键盘进行交互。因此,在运行该后台程序的同时,我们仍可在shell执行其他指令。
jobs查看后台任务列表,fg %n把后台编号为n的任务调到前台执行,kill %n结束后台编号为n的任务。
CTRL-Z中止前台任务,bg将中止的任务送入后台继续执行,bg %n继续执行后台之前已中止的序号为n的任务。
后台执行的程序无法获取终端输入,因此该程序执行到需要终端输入的部分时,将会在终端输出Stopped信息。我们可以在该程序需要输入的时候将其调到前台执行,或者利用重定向预指定该程序的标准输入从一个数据文件读入。
此外,由于程序的标准输出&错误输出默认都是输出到终端的,因此一般二者也需要进行重定向。
stty tostop可以使得后台程序的输出不直接输出到终端,而是通知终端说后台程序有输出信息,同时会中止该后台程序。
set –o notify可以将后台任务状态改变的信息立即传到前台终端。
参考:指令 stty 設定的影響
stty -tostop则是把后台程序直接输出至终端。
当一个程序在前台执行时,如果没有被预先重定向键盘输入,这些键盘输入内容就会作为该程序的标准输入。因此,在该程序执行完毕之前,前台无法执行其他指令,也就是前台每次只能执行一个程序。
当一个程序在后台执行时,该程序并不与键盘进行交互。因此,在运行该后台程序的同时,我们仍可在shell执行其他指令。
jobs查看后台任务列表,fg %n把后台编号为n的任务调到前台执行,kill %n结束后台编号为n的任务。
CTRL-Z中止前台任务,bg将中止的任务送入后台继续执行,bg %n继续执行后台之前已中止的序号为n的任务。
后台执行的程序无法获取终端输入,因此该程序执行到需要终端输入的部分时,将会在终端输出Stopped信息。我们可以在该程序需要输入的时候将其调到前台执行,或者利用重定向预指定该程序的标准输入从一个数据文件读入。
此外,由于程序的标准输出&错误输出默认都是输出到终端的,因此一般二者也需要进行重定向。
stty tostop可以使得后台程序的输出不直接输出到终端,而是通知终端说后台程序有输出信息,同时会中止该后台程序。
set –o notify可以将后台任务状态改变的信息立即传到前台终端。
参考:指令 stty 設定的影響
stty -tostop则是把后台程序直接输出至终端。
panll@HP1:~/tmp$ cat a.pl #!/usr/bin/perlkill –s SIGSTOP %n 在前台下kill指令暂停后台正在运行的,序号为n的任务。之后可以用bg或fg重新启动之。
sleep 5;
$x=;
print $x; panll@HP1:~/tmp$ perl a.pl & [1] 2748 panll@HP1:~/tmp$ jobs [1]+ Running perl a.pl & panll@HP1:~/tmp$ jobs [1]+ Stopped perl a.pl
13. Redirecting Input and Output
prog 2>file 把prog的stderr重定向到file。
prog >file 2>&1 把prog的stdout和stderr重定向到file。
prog <<c从键盘读入stdin,直至输入c。
prog 2>&1 | prog2 把prog的stdout和stderr传给prog2作为stdin。
prog < input > output 2>errors 指定prog的stdin从input读入,stdout输出到output,stderr输出到errors。
(cruncher 3>&1 1>&2 2>&3 3>&−) | mail yourname & 将cruncher的stderr传给mail作为stdin,将cruncher的stdout传到终端输出。
(cruncher 3>&1 >outputfile 2>&3 3>&−) | mail yourname & 将cruncher的stderr传给mail作为stdin,将cruncher的stdout输出到outputfile文件。
grep "^set" */.cshrc | more 中grep只把stdout传给more,而stderr传给终端输出,在grep报错的情况下,可能打乱more的屏幕输出,解决方案是将grep的 stderr也传给more,就如 grep "^set" */.cshrc 2>&1 | more 。
set noclobber可以防止重定向导致的错误,假设存在a.txt文件,但不存在b.txt文件 。
echo xxx >| a.txt 可以避免上面的提示,直接覆盖a.txt。
echo xxx >>| b.txt 可以避免上面的提示,直接新建b.txt写入。
noclobber不是环境变量,以故任何新的子shell不会继承之,欲其为默认属性,须在shell的setup file中set noclobber。
{ date; who; ls; } > log 将date, who, ls的输出全部重定向到log中。
(date; who; ls;) > log 效果同上,但是()启动了一个子shell,有额外开销。
()称为subshell operator,{}称为list operator。在list中cd子目录或set一个变量都影响本来的shell,而subshell不会,唯一的特例是{}后面加管道符|,具体见下:
例如
prog | tee prog.out | sed −f sedscr | tee sed.out | ...
使用tee保留中间程序的每一步输出。
tee –a filename 向filename里添加内容,同时在终端显示添加的内容。
tee –a b.txt < a.txt 将a.txt的内容添到b.txt末尾,同时在终端输出a.txt的内容。
(cat a.txt; cat b.txt)|tee c.txt 将前面()里一组程序的输出写入c.txt,同时在终端显示。
tpipe与tee类似,只是前者将程序输出同时重定向到多个管道。
例如
gzcat $f | tpipe lpr | sed −n "s/^%%Pages: \([0−9][0−9]*\)/$f: \1 pages/p"
通过tpipe将gzcat $f的内容两传给lpr跟sed。
- 表示从stdin读入,比如 rsh snooze cat bin/aprog | diff − aprog.new
sed 2q a.txt 输出a.txt的前两行。
prog >file 2>&1 把prog的stdout和stderr重定向到file。
prog <<c从键盘读入stdin,直至输入c。
prog 2>&1 | prog2 把prog的stdout和stderr传给prog2作为stdin。
prog < input > output 2>errors 指定prog的stdin从input读入,stdout输出到output,stderr输出到errors。
(cruncher 3>&1 1>&2 2>&3 3>&−) | mail yourname & 将cruncher的stderr传给mail作为stdin,将cruncher的stdout传到终端输出。
(cruncher 3>&1 >outputfile 2>&3 3>&−) | mail yourname & 将cruncher的stderr传给mail作为stdin,将cruncher的stdout输出到outputfile文件。
grep "^set" */.cshrc | more 中grep只把stdout传给more,而stderr传给终端输出,在grep报错的情况下,可能打乱more的屏幕输出,解决方案是将grep的 stderr也传给more,就如 grep "^set" */.cshrc 2>&1 | more 。
set noclobber可以防止重定向导致的错误,假设存在a.txt文件,但不存在b.txt文件 。
panll:/tmp$ set noclobber panll:/tmp$ echo xxx > a.txt zsh: 文件已存在: a.txt panll:/tmp$ echo xxx >> b.txt zsh: 没有那个文件或目录: b.txt可见set noclobber会提示文件覆盖以及文件不存在。
echo xxx >| a.txt 可以避免上面的提示,直接覆盖a.txt。
echo xxx >>| b.txt 可以避免上面的提示,直接新建b.txt写入。
noclobber不是环境变量,以故任何新的子shell不会继承之,欲其为默认属性,须在shell的setup file中set noclobber。
{ date; who; ls; } > log 将date, who, ls的输出全部重定向到log中。
(date; who; ls;) > log 效果同上,但是()启动了一个子shell,有额外开销。
()称为subshell operator,{}称为list operator。在list中cd子目录或set一个变量都影响本来的shell,而subshell不会,唯一的特例是{}后面加管道符|,具体见下:
$ { echo frep; foo=bar; } | cat frep $ echo $foo $ { echo frep; foo=bar; } frep $ echo $foo bartee可以将程序的stdout写入多个文件,同时输出到终端。
例如
prog | tee prog.out | sed −f sedscr | tee sed.out | ...
使用tee保留中间程序的每一步输出。
tee –a filename 向filename里添加内容,同时在终端显示添加的内容。
tee –a b.txt < a.txt 将a.txt的内容添到b.txt末尾,同时在终端输出a.txt的内容。
(cat a.txt; cat b.txt)|tee c.txt 将前面()里一组程序的输出写入c.txt,同时在终端显示。
tpipe与tee类似,只是前者将程序输出同时重定向到多个管道。
例如
gzcat $f | tpipe lpr | sed −n "s/^%%Pages: \([0−9][0−9]*\)/$f: \1 pages/p"
通过tpipe将gzcat $f的内容两传给lpr跟sed。
- 表示从stdin读入,比如 rsh snooze cat bin/aprog | diff − aprog.new
sed 2q a.txt 输出a.txt的前两行。
14. Moving Around in a Hurry
pwd找当前目录绝对路径的过程,找出当前目录.和父目录..的i-number,再到父目录中找当前目录i-number对应的名字,一级一级往
上走,直至到达/,那边..和.的i-number是相同的。见:14.4 How Does UNIX Find Your Current
Directory?
$CDPATH的作用是,假如export CDPATH=:$HOME:$HOME/projects:/books/troff,接着cd foo,如果当前目录下并没有子目录名为foo,则shell会自动再去找$HOME/foo,$HOME/projects/foo,/book /troff/foo。
pushd和popd见:linux中利用Pushd/popd頻繁切換目錄
$CDPATH的作用是,假如export CDPATH=:$HOME:$HOME/projects:/books/troff,接着cd foo,如果当前目录下并没有子目录名为foo,则shell会自动再去找$HOME/foo,$HOME/projects/foo,/book /troff/foo。
pushd和popd见:linux中利用Pushd/popd頻繁切換目錄
pushd 若有参数就跳到那个目录,并将原目录压入堆栈。若无参数便回到上一个目录,并将堆栈中最近的两个目录交换。 popd 若无参数就回到上一个目录且弹出堆栈中最近的目录。若有参数则仅仅弹出堆栈中最底层的目录。(工作目录不变) dirs 列出堆栈中的目录。
15. Wildcards
grep –l abc file1 file2 file3 > filelist 将file1/file2/file3中包含abc的文件名存入filelist文件中。
-l 表示只列出匹配搜寻条件的文件名,且某文件一旦匹配立即停止在该文件中的搜寻。不加-l则会打印所有匹配的行。
grep –c “abc” file 则返回abc在file中出现的次数。
grep −c "\.XX" * | sed −n s/:0//p > ../not_indexed.list 返回不含.XX的文件列表。
ls –d */ 列出所有子目录。
-l 表示只列出匹配搜寻条件的文件名,且某文件一旦匹配立即停止在该文件中的搜寻。不加-l则会打印所有匹配的行。
grep –c “abc” file 则返回abc在file中出现的次数。
grep −c "\.XX" * | sed −n s/:0//p > ../not_indexed.list 返回不含.XX的文件列表。
ls –d */ 列出所有子目录。
16. Where Did I Put That?
ls –t 按修改时间(modification time)排序,最近修改的在前面。ls -tr则是最近修改的在后面。
ls –tu 按访问时间(access time)排序,最近访问的在前面。
ls –tc 按文件inode最后修改时间(change time)排序,最近修改的在前面。
ls –x 行优先输出文件名。
ls –F 在目录名后面多加个/,在可执行文件后面多加个*,在链接文件后面多加个@,在socket文件后面多加个=。
ls –d [a-c]* 列出匹配[a-c]*的文件及目录名,-d表示不列出子目录中的具体内容,且不去找符号链接对应的目录。
cat –e 在每行结束处加个$标记。
搜寻档案或目录: which, whereis, locate, find
ls –b 列出含非打印字符的文件名
date +’%m%d’ 指定输出月份和日期
统计各种类型的文件数目:
find . −type l −print | perl −nle '−e || print' 列出失效链接
ls –tu 按访问时间(access time)排序,最近访问的在前面。
ls –tc 按文件inode最后修改时间(change time)排序,最近修改的在前面。
ls –x 行优先输出文件名。
ls –F 在目录名后面多加个/,在可执行文件后面多加个*,在链接文件后面多加个@,在socket文件后面多加个=。
ls –d [a-c]* 列出匹配[a-c]*的文件及目录名,-d表示不列出子目录中的具体内容,且不去找符号链接对应的目录。
cat –e 在每行结束处加个$标记。
搜寻档案或目录: which, whereis, locate, find
ls –b 列出含非打印字符的文件名
date +’%m%d’ 指定输出月份和日期
统计各种类型的文件数目:
#!/bin/shls -t .|head –1 找出当前目录下最新的文件(最近修改的)
# usage: count_types [directory ...]
# Counts how many files there are of each type
# Original by Bruce Barnett
# Updated version by yu@math.duke.edu (Yunliang Yu)
find ${*−.} −type f −print | xargs file |
awk '{
$1=NULL;
t[$0]++;
}
END {
for (i in t) printf("%d\t%s\n", t[i], i);
}' | sort −nr # Sort the result numerically, in reverse
find . −type l −print | perl −nle '−e || print' 列出失效链接
没有评论:
发表评论