📄 8.htm
字号:
$ dos2unix <VAR>dosfile</VAR>
</PRE>
<HR>
<A name=s8.6.12></A>
<H3>8.6.12 正规表达式的置换</H3>
<P>将所有文件<VAR>FILES</VAR> ...中的所有<VAR>FROM_REGEX</VAR>字段替换成<VAR>TO_REGEX</VAR>字段。
<PRE> $ perl -i -p -e 's/<VAR>FROM_REGEX</VAR>/<VAR>TO_REGEX</VAR>/g;' <VAR>FILES</VAR> ...
</PRE>
<P><SAMP>-i</SAMP>表示“就地编辑”,<SAMP>-p</SAMP>表示“在<VAR>FILES</VAR>...各文件中循环”。如果置换很复杂,应使用参数<SAMP>-i.bak</SAMP>而非<SAMP>-i</SAMP>,这有助于出错恢复;它会将每个原始文件保存为以<SAMP>.bak</SAMP>为后缀的备份文件。
<HR>
<A name=s8.6.13></A>
<H3>8.6.13 使用脚本来编辑文件</H3>
<P>下面的脚本将删除5-10行以及16-20行。 <PRE> #!/bin/bash
ed $1 <<EOF
16,20d
5,10d
w
q
EOF
</PRE>
<P>在此,<CODE>ed</CODE>命令与<CODE>vi</CODE>命令模式下的是一样的,从外部编辑文件的方式使它更适于脚本化。
<HR>
<A name=s8.6.14></A>
<H3>8.6.14 提取源文件修改部分合并到更新包</H3>
<P>下面的操作将根据文件位置,提取源文件的修改部分并创建统一的diff文件<VAR>file.patch0</VAR>或<VAR>file.patch1</VAR>:
<PRE> $ diff -u <VAR>file.old</VAR> <VAR>file.new1</VAR> > <VAR>file.patch0</VAR>
$ diff -u <VAR>old/file</VAR> <VAR>new1/file</VAR> > <VAR>file.patch1</VAR>
</PRE>
<P>diff文件(也称补丁文件)通常用于发送程序更新。收到的补丁文件可使用下面的方法更新另一个<VAR>文件</VAR>: <PRE> $ patch -p0 <VAR>file</VAR> < <VAR>file.patch0</VAR>
$ patch -p1 <VAR>file</VAR> < <VAR>file.patch1</VAR>
</PRE>
<P>如果有3个版本的源代码,使用<CODE>diff3</CODE>来合并效率更高: <PRE> $ diff3 -m <VAR>file.mine</VAR> <VAR>file.old</VAR> <VAR>file.yours</VAR> > <VAR>file</VAR>
</PRE>
<HR>
<A name=s8.6.15></A>
<H3>8.6.15 分割大文件</H3><PRE> $ split -b 650m <VAR>file</VAR> # 将大文件分块成多个650MB的小文件
$ cat x* ><VAR>largefile</VAR> # 将所有小文件合并成一个大文件
</PRE>
<HR>
<A name=s8.6.16></A>
<H3>8.6.16 从文本格式的表格中抽取数据</H3>
<P>假设有一个文本文件名为<CODE>DPL</CODE>,其中存放着所有前Debian项目领导人的名字和他们的上台日期,表格格式是以空格做为分隔的。 <PRE> Ian Murdock August 1993
Bruce Perens April 1996
Ian Jackson January 1998
Wichert Akkerman January 1999
Ben Collins April 2001
Bdale Garbee April 2002
Martin Michlmayr March 2003
</PRE>
<P>AWK经常用于从这类数据中提取数据。 <PRE> $ awk '{ print $3 }' <DPL # month started
August
April
January
January
April
April
March
$ awk '($1=="Ian") { print }' <DPL # DPL called Ian
Ian Murdock August 1993
Ian Jackson January 1998
$ awk '($2=="Perens") { print $3,$4 }' <DPL # When Perens started
April 1996
</PRE>
<HR>
<A name=s8.6.17></A>
<H3>8.6.17 精巧的管道命令辅助脚本</H3>
<P>下列脚本做为管道的一部分十分有用。 <PRE> find /usr | egrep -v "/usr/var|/usr/tmp|/usr/local"
# find all files in /usr excluding some files
xargs -n 1 <VAR>command</VAR> # run command for all items from stdin
xargs -n 1 echo | # split white-space-separated items into lines
xargs echo | # merge all lines into a line
grep -e <VAR>pattern</VAR>| # extract lines containing <VAR>pattern</VAR>
cut -d: -f3 -|
# extract third field separated by : (passwd file etc.)
awk '{ print $3 }' | # extract third field separated by whitespaces
awk -F'\t' '{ print $3 }' |
# extract third field separated by tab
col -bx | # remove backspace and expand tabs to spaces
expand -| # expand tabs
sort -u| # sort and remove duplicates
tr '\n' ' '| # concatenate lines into one line
tr '\r' ''| # remove CR
tr 'A-Z' 'a-z'| # convert uppercase to lowercase
sed 's/^/# /'| # make each line a comment
sed 's/\<VAR>.ext</VAR>//g'| # remove <VAR>.ext</VAR>
sed -n -e 2p| # print the second line
head -n 2 -| # print the first 2 lines
tail -n 2 -| # print the last 2 lines
</PRE>
<HR>
<A name=s8.6.18></A>
<H3>8.6.18 短小的Perl脚本</H3>
<P>任何Awk脚本均可使用Perl重写,例如 <PRE> awk '($2=="1957") { print $3 }' |
</PRE>
<P>可以使用下列任意一行实现: <PRE> perl -ne '@f=split; if ($f[1] eq "1957") { print "$f[2]\n"}' |
perl -ne 'if ((@f=split)[1] eq "1957") { print "$f[2]\n"}' |
perl -ne '@f=split; print $f[2] if ( $f[1]==1957 )' |
perl -lane 'print $F[2] if $F[1] eq "1957"' |
</PRE>
<P>其实上面各行中所有perl参数中的空格均可去掉,这得益于Perl的数字字符串自动转换功能。 <PRE> perl -lane 'print$F[2]if$F[1]eq+1957' |
</PRE>
<P>有关命令行参数的信息可参阅<CODE>perlrun(1)</CODE>,在<CODE><A
href="http://perlgolf.sourceforge.net/">http://perlgolf.sourceforge.net/</A></CODE>有更多令人着魔的Perl脚本,你会感兴趣的。
<HR>
<A name=s8.6.19></A>
<H3>8.6.19 从网页上获取文本或邮件列表文档</H3>
<P>下面的操作将网页转化为文本文件。从网上拷贝配置文件时十分有用。 <PRE> $ lynx -dump http://<VAR>www.remote-site.com/help-info.html</VAR> ><VAR>textfile</VAR>
</PRE>
<P><CODE>links</CODE>和<CODE>w3m</CODE>也可以这么用,只是生成的文本样式可能略有不同。
<P>如果是邮件列表文档,可使用<CODE>munpack</CODE>从文本获得mime内容。
<HR>
<A name=s8.6.20></A>
<H3>8.6.20 打印网页</H3>
<P>下面的操作将网页内容打印成PostScript文件或发送到打印机。 <PRE> $ apt-get install html2ps
$ html2ps <VAR>URL</VAR> | lpr
</PRE>
<P>参阅<A
href="http://qref.sourceforge.net/Debian/reference/ch-install.zh-cn.html#s-lprlpd"><CODE>lpr</CODE>/<CODE>lpd</CODE>,
第 3.6.1 节</A>。还可使用<CODE>a2ps</CODE>和<CODE>mpage</CODE>软件包生成PostScript文件。
<HR>
<A name=s8.6.21></A>
<H3>8.6.21 打印帮助页面</H3>
<P>下面的操作将帮助页面打印成PostScript文件或发送到打印机。 <PRE> $ man -Tps <VAR>some-man-page</VAR> | lpr
$ man -Tps <VAR>some-man-page</VAR> | mpage -2 | lpr
</PRE>
<HR>
<A name=s8.6.22></A>
<H3>8.6.22 合并两个Postscript或PDF文件</H3>
<P>可以将两个Postscript文件或PDF文件合并。 <PRE> $ gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite \
-sOutputFile=<VAR>bla.ps</VAR> -f <VAR>foo1.ps</VAR> <VAR>foo2.ps</VAR>
$ gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
-sOutputFile=<VAR>bla.pdf</VAR> -f <VAR>foo1.pdf</VAR> <VAR>foo2.pdf</VAR>
</PRE>
<HR>
<A name=s8.6.23></A>
<H3>8.6.23 命令耗时</H3>
<P>显示某进程的耗时 <PRE> # time <VAR>some-command</VAR> >/dev/null
real 0m0.035s # time on wall clock (elapsed real time)
user 0m0.000s # time in user mode
sys 0m0.020s # time in kernel mode
</PRE>
<HR>
<A name=s8.6.24></A>
<H3>8.6.24 <CODE>nice</CODE>命令</H3>
<P>使用<CODE>nice</CODE>(来自GNU
<CODE>shellutils</CODE>软件包)可设置命令启动时的nice值。<CODE>renice</CODE>(<CODE>bsdutils</CODE>)或<CODE>top</CODE>可以重设进程的nice值。nice值为19代表最慢的(优先级最低的)进程;负值就“not-nice”,如-20代表非常快的(优先级高的)进程。只有超级用户可以设定负nice值。
<PRE> # nice -19 <VAR>top</VAR> # very nice
# nice --20 <VAR>cdrecord -v -eject speed=2 dev=0,0 disk.img</VAR> # very fast
</PRE>
<P>有时极端的nice值对系统弊大于利,所以使用该命令要小心。
<HR>
<A name=s-cronjob></A>
<H3>8.6.25 日程安排(<CODE>cron</CODE>,<CODE>at</CODE>)</H3>
<P>在Linux下使用<CODE>cron</CODE>和<CODE>at</CODE>进行任务日程安排。参阅<CODE>at(1)</CODE>、<CODE>crontab(5)</CODE>、<CODE>crontab(8)</CODE>。
<P>执行命令<SAMP>crontab
-e</SAMP>创建或编辑crontab文件,为规律事务(按周期循环的事务)安排日程。下面的一个crontab文件样例: <PRE> # use /bin/sh to run commands, no matter what /etc/passwd says
SHELL=/bin/sh
# mail any output to `paul', no matter whose crontab this is
MAILTO=paul
# Min Hour DayOfMonth Month DayOfWeek command (Day... are OR'ed)
# run at 00:05, every day
5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 14:15 on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 22:00 on weekdays(1-5), annoy Joe. % for newline, last % for cc:
0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%.%%
23 */2 1 2 * echo "run 23 minutes after 0am, 2am, 4am ..., on Feb 1"
5 4 * * sun echo "run at 04:05 every sunday"
# run at 03:40 on the first Monday of each month
40 3 1-7 * * [ "$(date +%a)" == "Mon" ] && command -args
</PRE>
<P>执行<CODE>at</CODE>命令为偶然任务(只执行一次的任务)安排日程: <PRE> $ echo '<VAR>command -args</VAR>'| at 3:40 monday
</PRE>
<HR>
<A name=s-screen></A>
<H3>8.6.26 用<CODE>screen</CODE>来定制控制台</H3>
<P>The
<CODE>screen</CODE>程序允许在<STRONG>单一</STRONG>的物理终端或终端模拟窗口运行<STRONG>多个</STRONG>伪终端,每个伪终端都拥有自己的交互式shell。即便可以使用Linux伪终端或多个xterm窗口,研究一下如何设置<CODE>screen</CODE><STRONG>丰富的特性</STRONG>仍很有益,这些特性包括:
<UL>
<LI>回溯历史显示,
<LI>拷贝和粘贴,
<LI>输出到日志,
<LI>图形入口,
<LI>将终端与整个<CODE>screen</CODE>会话<STRONG>分离</STRONG>,稍后再连接。 </LI></UL>
<HR>
<A name=s8.6.26.1></A>
<H4>8.6.26.1 远程访问方案</H4>
<P>If you frequently log on to a Linux machine
如果你经常从远程终端登录到Linux机器或使用VT100终端程序,<CODE>screen</CODE>的<STRONG>detach</STRONG>(分离)特性将简化你的生活。
<OL type=1>
<LI>通过拔号连接登录,运行了一个非常复杂的<CODE>screen</CODE>会谈,打开了好几个窗口,有编辑器和其它一些程序。
<LI>突然你需要离开终端一下,但你并不想挂断连接中止工作。
<LI>输入<SAMP>^A d</SAMP><STRONG>离开</STRONG>会话,然后登出系统。(或者更简单些,输入<SAMP>^A
DD</SAMP>离开会话并自动登出系统)
<LI>当你回来时,需要再次登录,可输入命令<SAMP>screen
-r</SAMP>,<CODE>screen</CODE>会如魔法般地重新连接上所有打开的窗口。 </LI></OL>
<HR>
<A name=s8.6.26.2></A>
<H4>8.6.26.2 典型的<CODE>screen</CODE>命令</H4>
<P>一但打开了<CODE>screen</CODE>程序,除了命令按键(默认为<SAMP>^A</SAMP>)所有的键盘输入都被送到当前窗口,所有的<CODE>screen</CODE>命令均按特定方式输入:<SAMP>^A</SAMP>加一个单键命令[加一些参数]的。常用的命令有:
<PRE> ^A ? 显示帮助屏幕(显示命令集)
^A c 创建并切换到新窗口
^A n 跳到下一个窗口
^A p 跳到上一个窗口
^A <VAR>0</VAR> 跳到<VAR>0</VAR>号窗口
^A w 显示窗口列表
^A a 将Ctrl-A做为键盘输入发送到当前窗口
^A h 对当前窗口做硬拷贝写入到文件
^A H 开始/中止将当前窗口事件记录到文件
^A ^X 锁定终端(密码保护)
^A d 从终端分离屏幕会话
^A DD 分离屏幕会话并退出登录
</PRE>
<P>以上只是<CODE>screen</CODE>命令的一个很小的子集。只要是你认为<CODE>screen</CODE>能干的事,没准它真就可以!详情参阅<CODE>screen(1)</CODE>。
<HR>
<A name=s8.6.26.3></A>
<H4>8.6.26.3 <CODE>screen</CODE>会话中的退格键和Ctrl-H</H4>
<P>在运行<CODE>screen</CODE>时,如果发现退格键和/或Ctrl-H无法正常工作,可编辑<CODE>/etc/screenrc</CODE>,找到这行:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -