UNIX文本处理全攻略:从基础到高级应用
利用make工具优化文档处理流程
在文档制作的最后阶段,有诸多细节需要用户留意。为确保文档的最终生成万无一失,
make
工具能发挥巨大作用。以下是一些需要确保完成的事项:
1. 所有相关章节都以最新版本打印,防止文件的最后修改未被纳入印刷版。
2. 利用自动工具对书籍进行校对,如
proof
和
double
脚本(若有
wwb
也可使用),同时要满足并移除文本中嵌入的所有“审核注释”。
3. 打印更新后的目录和索引。
make
工具虽然能指定书籍各部分所需的文件和格式选项,但存在占用大量磁盘空间来保存格式化输出文件的问题。不过,我们可以通过创建零长度文件来解决这一限制。具体操作是在格式化源文件时,使用
touch
命令更新该零长度文件。例如,在
format
脚本末尾添加
touch print/$file
,或者将
touch
命令放入
makefile
中。
下面是一个简单的
makefile
示例:
book : print/ch01 print/ch02 print/ch03 ...
print/ch01 : ch01
sh /usr/local/bin/format -mS -rvl -rS2 ch01
touch print/ch01
print/ch02 : ch02
sh /usr/local/bin/format -mS -P -rvl -rS2 ch02
touch print/ch02
为了使
makefile
更具通用性和易修改性,可以使用变量:
FORMAT: sh /usr/local/bin/format
OPTIONS: -mS -P -rvl -rS2
book : print/ch01 print/ch02 print/ch03 ...
print/ch01 : ch01
$(FORMAT) $(OPTIONS) ch01
touch print/ch01
print/ch02 : ch02
$(FORMAT) $(OPTIONS) ch02
touch print/ch02
make
使用的变量设置方式与shell变量类似,但引用时需用括号括起来并加上美元符号。用户可以轻松编辑
OPTIONS
变量来添加或移除选项。
为了确保索引和目录的更新,可在
makefile
中添加以下依赖关系和创建指令:
book: print/ch01 ... proof/ch01 ... book-index book-toc
print/ch01 : ch01
book-index : index/ch01 index/ch02 ...
cat index/* | sh /usr/local/bin/indexprog > book-index
book.toc : toc/ch01 ... figlist/ch01 ... tablist/ch01 ...
echo .ta \n(LLu-5n \n(LLuR > book-toc
echo .ce >> book-toc
echo \f3TABLE OF CONTENTS\fP >> book-toc
echo .sp 2 >> book-toc
echo "\t\f3Page\fP" >> book-toc
cat toc/ch01 ... toc/appz >> book-toc
echo ' .bp' >> book-toc
cat figlist/ch01 ... figlist/appz >> book-toc
echo ' .bp' >> book-toc
cat tablist/ch01 ... tablist/appz >> book-toc
toc/ch01 : ch01
$(FORMAT) $(OPTIONS) -X ch01
toc/ch02 : ch02
$(FORMAT) $(OPTIONS) -X ch02
index/ch01 : ch01
$(FORMAT) $(OPTIONS) -X ch01
figlist/ch01 : ch01
$(FORMAT) $(OPTIONS) -X ch01
tablist/ch01 : ch01
$(FORMAT) $(OPTIONS) -X ch01
通过输入
$ make book.toc
,系统会自动编译目录。若文件有更改,会重新格式化源文件以生成新的目录条目。
此外,还可以添加其他“目标”,如检查每章是否校对。创建一个伪目标
proof
,当输入
$ make proof
时,会根据
makefile
中的规则自动强制校对文档。
print
目录也可作为伪目标,方便打印单个章节。输入
$ make book
,可一次性打印整本书及其附属内容。若想在执行时不显示格式化命令,可使用
-s
选项或在
makefile
顶部添加
.SILENT:
。
为了简化复杂
makefile
的创建过程,可以编写一个shell脚本
buildmake
:
if [ $# -eq 0 ]; then
echo 'USAGE : buildmake files'
echo ' (You must specify the files that make up the book)'
exit
fi
if [ ! -d print ]; then
mkdir print
mkdir proof
fi
if [ ! -d index ]; then
mkdir index
fi
if [ ! -d toc ]; then
mkdir toc
mkdir figlist
mkdir tablist
fi
for x; do
prifiles="$prifiles print/$x"
profiles="$profiles proof/$x"
tcfiles="$tcfiles toc/$x"
xfiles="$xfiles index/$x"
fgfiles="$fgfiles figlist/$x"
tbfiles="$tbfiles toc/$x"
done
echo ".SILENT:" > makefile
echo "FORMAT = sh /usr/local/bin/format" >> makefile
echo "OPTIONS = -mS" >> makefile
echo "INDEXPROG = sh /usr/local/bin/indexprog" >> makefile
echo "book : $prifiles $profiles book-toc book.index" >> makefile
echo "book.index : $xfiles/" >> makefile
echo -e "\tcat $xfiles | $(INDEXPROG) > book.index" >> makefile
echo -e "\t$(FORMAT) $(OPTIONS) book.index" >> makefile
echo "book-toc : $tcfiles" >> makefile
echo -e "\techo .ta \n(LLu-5n \n(LLuR > book-toc" >> makefile
echo -e "\techo .ce >> book-toc" >> makefile
echo -e "\techo \f3TABLE OF CONTENTS\fP >> book-toc" >> makefile
echo -e "\techo .sp 2 >> book-toc" >> makefile
echo -e "\techo \"\t\f3Page\fP\" >> book-toc" >> makefile
echo -e "\tcat /work/lib/toc - top > book-toc" >> makefile
echo -e "\tcat $tcfiles >> book-toc" >> makefile
echo -e "\techo .bp >> book-toc" >> makefile
echo -e "\tcat $fgfiles >> book-toc" >> makefile
echo -e "\techo .bp >> book-toc" >> makefile
echo -e "\tcat $tbfiles >> book-toc" >> makefile
echo -e "\t$(FORMAT) $(OPTIONS) book-toc" >> makefile
for x; do
echo "print/$x : $x" >> makefile
echo -e "\t$(FORMAT) $(OPTIONS) $x" >> makefile
echo "proof/$x : $x" >> makefile
echo -e "\techo $x has not been proofed" >> makefile
echo "toc/$x : $x" >> makefile
echo -e "\t$(FORMAT) $(OPTIONS) -x $x" >> makefile
echo "index/$x : $x" >> makefile
echo -e "\t$(FORMAT) $(OPTIONS) -x $x" >> makefile
done
用户只需输入
$ buildmake files
,即可创建复杂的
makefile
,还可手动编辑指定格式化选项的第一行。
UNIX文本处理工具命令总结
UNIX中有多种文本处理工具,下面将对其命令进行详细总结。
模式匹配语法
许多UNIX文本处理程序(如
ed
、
ex
、
vi
、
sed
和
grep
)支持通过文本模式(正则表达式)进行搜索和替换。正则表达式由普通字符和特殊字符组合而成,以下是一些特殊字符及其用途:
| 特殊字符 | 用途 |
| ---- | ---- |
|
.
| 匹配除换行符外的任何单个字符 |
|
*
| 匹配前一个字符(包括正则表达式指定的字符)的任意数量(包括零个) |
|
[ ]
| 匹配方括号内的任意一个字符,可指定字符范围,如
[A-Z]
,若以
^
开头则匹配方括号外的字符 |
|
\{n,m\}
| 匹配前一个字符的出现次数范围,
\{n\}
表示精确匹配n次,
\{n,\}
表示至少匹配n次,
\{n,m\}
表示匹配n到m次 |
|
^
| 要求后续正则表达式出现在行首 |
|
$
| 要求前面的正则表达式出现在行尾 |
|
\
| 将后续特殊字符视为普通字符 |
|
\(\)
| 将括号内的模式保存到特殊空间,最多可保存9个模式,可通过
\1
-
\9
在替换中“重放” |
|
\n
| 匹配之前由
\(\)
保存的第n个模式 |
egrep
和
awk
还使用扩展的元字符集:
| 元字符 | 用途 |
| ---- | ---- |
|
regexp+
| 匹配正则表达式的一次或多次出现 |
|
regexp?
| 匹配正则表达式的零次或一次出现 |
|
regexp \| regexp
| 匹配包含任一正则表达式的行 |
|
(regexp)
| 用于复杂正则表达式的分组 |
ex
中的正则表达式还有一些不同的扩展:
| 扩展 | 用途 |
| ---- | ---- |
|
\<
| 限制后续模式仅在单词开头匹配 |
|
\>
| 限制后续模式仅在单词结尾匹配 |
|
\u
| 附加到替换字符串,将替换字符串的首字符转换为大写 |
|
\U
| 附加到替换字符串,将整个替换字符串转换为大写 |
|
\l
| 附加到替换字符串,将替换字符串的首字符转换为小写 |
|
\L
| 附加到替换字符串,将整个替换字符串转换为大写 |
vi编辑器
-
命令行语法
:有两种方式调用
vi编辑器:vi [options] file(s)或vi view file(s)。若未指定文件名,vi会打开一个可通过:f命令命名或在保存时命名的文件。若指定多个文件,第一个文件将被打开编辑,使用:n可打开下一个文件。view命令以只读模式打开第一个文件,更改无法保存。-
选项
:
-
-l:打开文件编辑LISP程序 -
-r:恢复文件 -
-R:以只读模式打开文件,与view相同 -
-ttag:从标签开始 -
-X:打开加密文件 -
+:打开文件到最后一行 -
+ n:打开文件到第n行 -
+ /pattern:打开文件到模式的首次出现位置 -
-wn:将窗口设置为n行
-
-
选项
:
-
操作模式
:文件打开后进入命令模式,可从命令模式进入插入模式、执行编辑命令、移动光标、调用
ex命令或UNIX shell、保存或退出文件。以下命令可进入插入模式:a A i I o O R s S,在插入模式下可输入新文本,按ESCAPE键返回命令模式。 -
命令语法
:编辑命令的语法为
[n] operator [n] object,其中operator是基本编辑操作符(如c- 更改、d- 删除、y- 复制),object是定位光标在文件中的命令(如word、sentence、paragraph、section等),n表示操作执行的次数或操作的对象数量。 -
状态行命令
:大多数命令输入时不在屏幕上回显,但以下命令在屏幕底部的状态行回显:
-
/、?:开始向前或向后的模式匹配搜索 -
*:调用ex命令 -
!:调用以缓冲区对象为输入并将输出替换该对象的UNIX命令 -
状态行输入的命令需按
RETURN键执行,错误消息和*G命令的输出也显示在状态行。
-
以下是
vi
命令的部分总结:
| 命令 | 用途 |
| ---- | ---- |
|
" @
| 重复上一个命令(插入、更改或删除) |
|
@buffer
| 执行缓冲区中存储的命令 |
|
a
| 在光标后追加文本 |
|
A
| 在行尾追加文本 |
|
b
| 后退到当前行单词的开头 |
|
B
| 后退到单词,忽略标点符号 |
|
c
| 更改操作符 |
|
d
| 删除操作符 |
|
e
| 移动到单词末尾 |
|
f
| 在当前行向前查找下一个输入的字符 |
|
F
| 在当前行向后查找下一个输入的字符 |
|
^F
| 向前滚动一个窗口 |
|
g
| 未使用 |
|
G
| 转到指定行或文件末尾 |
|
^G
| 在状态行打印文件信息 |
|
h
| 左箭头光标键 |
|
H
| 将光标移动到起始位置 |
|
i
| 在光标前插入文本 |
|
I
| 在行首插入文本 |
|
J
| 连接两行 |
|
k
| 上箭头光标键 |
|
l
| 右箭头光标键 |
|
L
| 将光标移动到窗口的最后一个位置 |
|
m
| 在寄存器(a - z)中标记当前光标位置 |
|
M
| 将光标移动到窗口的中间位置 |
|
n
| 重复上一个搜索命令 |
|
N
| 反向重复上一个搜索命令 |
|
o
| 在当前行下方打开一行 |
|
O
| 在当前行上方打开一行 |
|
p
| 将复制或删除的文本放在光标后或下方 |
|
P
| 将复制或删除的文本放在光标前或上方 |
|
q
| 退出
vi
并调用
ex
|
|
r
| 用下一个输入的字符替换光标处的字符 |
|
R
| 替换字符 |
|
s
| 更改光标下的字符为输入的字符 |
|
S
| 更改整行 |
|
t
| 将光标向前移动到下一个输入字符之前的字符 |
|
T
| 将光标向后移动到下一个输入字符之后的字符 |
|
u
| 撤销上一次更改 |
|
U
| 恢复当前行,丢弃更改 |
|
v
| 未使用 |
|
V
| 未使用 |
|
w
| 移动到下一个单词的开头 |
|
W
| 移动到下一个单词的开头,忽略标点符号 |
|
x
| 删除光标下的字符 |
|
X
| 删除光标前的字符 |
|
y
| 复制操作符 |
|
Y
| 复制当前行 |
|
z
| 重绘屏幕,根据后续的
CR
(顶部)、
.
(中间)、
-
(底部)重新定位光标 |
|
ZZ
| 退出编辑器,保存更改 |
vi
的
set
选项可通过
:set
命令指定,以下是部分选项:
| 选项(缩写) | 默认值 | 描述 |
| ---- | ---- | ---- |
|
autoindent (ai)
|
noai
| 每行缩进与上一行相同的级别,与
shiftwidth
选项一起使用 |
|
autoprint (ap)
| | 每次编辑器命令后显示更改(全局替换时显示最后一次替换) |
|
autowrite (aw)
|
noaw
| 如果文件在使用
:n
打开另一个文件或使用
:!
执行UNIX命令之前有更改,自动保存文件 |
|
beautify (bf)
|
nobf
| 输入时忽略所有控制字符(除制表符、换行符或换页符) |
|
directory (dir)
|
=tmp
| 指定
ex
存储缓冲区文件的目录(目录必须可写) |
|
edcompatible
|
noed-compatible
| 在替换命令中使用类似
ed
的功能 |
|
errorbells (eb)
|
errorbells = 8
| 错误消息响铃 |
|
hardtabs (ht)
| | 定义终端硬件制表符的边界 |
|
ignorecase (ic)
|
noic
| 搜索时忽略大小写 |
|
lisp
|
nolisp
| 以适当的LISP格式插入缩进,
()
、
{}
、
[[
和
]]
具有LISP含义 |
|
list
|
nolist
| 制表符打印为
\|
,行尾标记为
$
,用于区分行尾字符是制表符还是空格 |
|
magic
|
magic
| 通配符
. * [
在模式中具有特殊含义 |
|
mesg
|
mesg
| 允许在
vi
编辑时在终端显示消息 |
|
number (nu)
|
nonu
| 在编辑会话期间在屏幕左侧显示行号 |
|
open
|
open
| 允许从
ex
进入打开或可视模式 |
|
optimize (opt)
|
noopt
| 打印多行时删除行尾的回车符,在打印带有前导空白的行时加快哑终端的输出速度 |
|
paragraphs (para)
|
=IPLPPPQP LIPPlPiPbP
| 定义段落分隔符,用于
(
或
I
移动 |
|
prompt
|
prompt
| 设置
ex
提示符
:
|
|
readonly (ro)
|
nor0
| 除非在写入(
w
、
ZZ
或
autowrite
)后使用
!
,否则任何文件写入操作将失败 |
|
redraw (re)
|
noredraw
| 编辑时终端重绘屏幕,默认值取决于行速度和终端类型,
noredraw
在慢速哑终端上有用 |
|
remap
|
remap = 5
| 允许嵌套映射序列 |
|
report
| | 触发屏幕底部警告消息的大编辑操作的大小(即单个编辑影响的行数) |
|
scroll
|
= [1/2 window]
| 屏幕滚动的量 |
|
sections
|
=SHNHH HU
| 定义章节分隔符,用于
{ }
移动 |
|
shell (sh)
|
/bin/sh
| 用于shell转义(
:!
)和shell命令(
:sh
)的shell路径名,值从shell环境派生 |
|
shiftwidth (sw)
|
sw = a
| 定义使用
>>
或
<<
命令在
autoindent
选项中缩进的空格数 |
|
showmatch (sm)
|
nosm
| 在
vi
中输入
)
或
]
时,光标短暂移动到匹配的
(
或
{
,若匹配不在屏幕上则响铃,对编程非常有用 |
|
showmode (smd)
|
nosmd
| 输入模式时在命令行打印
Input Mode
字符串(仅适用于System V, Release 2
vi
) |
|
slowopen (slow)
| | 插入时暂停显示,默认值取决于行速度和终端类型 |
|
tabstop (ts)
|
= 8
| 设置编辑会话期间制表符缩进的空格数(打印机仍使用系统制表符8) |
|
taglength (tl)
|
= 0
| 定义标签的有效字符数,默认值为0表示所有字符都有效 |
|
tags
|
=tags
| 包含标签的文件路径名,默认情况下系统搜索
/usr/lib/tags
和当前目录中的
tags
文件 |
|
term
| | 终端类型 |
|
terse
|
noterse
| 显示更简洁的错误消息 |
|
timeout
|
timeout
| 宏在1秒后“超时” |
|
tttype
| | 终端类型 |
|
warn
|
warn
| 显示“自上次更改后未写入”的警告 |
|
window (W)
| | 在屏幕上显示文件的一定行数,默认值取决于行速度和终端类型 |
|
wrapscan (ws)
|
ws
| 搜索环绕文件末尾 |
|
wrapmargin (wm)
|
= 0
| 定义右边界,若大于零则自动插入回车符断行 |
|
writeany (wa)
|
nowa
| 允许保存到任何文件 |
mermaid流程图如下:
graph LR
A[开始] --> B[打开文件]
B --> C{命令模式}
C --> D[插入模式]
C --> E[编辑命令]
C --> F[移动光标]
C --> G[调用ex命令]
C --> H[调用UNIX shell]
C --> I[保存或退出]
D --> C[按ESC返回命令模式]
以上就是UNIX文本处理中
make
工具和
vi
编辑器的相关内容,掌握这些知识可以帮助你更高效地进行文本处理和文档制作。
ex编辑器
ex
编辑器是一种行编辑器,也是屏幕编辑器
vi
的基础。所有
ex
命令都作用于文件中的当前行或一系列行。在
vi
中,
ex
命令需以冒号开头,并通过按
RETURN
键执行;在
ex
本身中,冒号作为提示符。
要从UNIX提示符进入
ex
,可使用命令:
ex filename
,同时也可使用调用
vi
时的选项。在
vi
中,可使用
Q
命令退出
vi
并进入
ex
。退出
ex
的命令如下:
-
x
:退出并保存更改
-
q!
:不保存更改直接退出
-
vi
:从
ex
进入
vi
在
vi
中输入
ex
命令的格式为:
:address command options
,其中冒号表示
ex
命令,
address
是行号或行范围,是命令的作用对象。命令可使用以下选项:
| 选项 | 用途 |
| ---- | ---- |
|
parameters
| 表示可提供额外信息,参数可以是文件名 |
|
count
| 命令重复执行的次数 |
|
flag
| 表示命令的变体形式 |
|
#, p, 和 l
| 表示打印格式 |
需注意,与
vi
命令不同,
count
不能放在命令前面,否则会被当作地址。例如,
d3
表示从当前行开始删除三行,而
3d
表示删除第三行。输入地址和命令时,会在状态行回显,按
RETURN
键执行命令。
地址的指定规则如下:
- 若未指定地址,命令作用于当前行。
- 若指定行范围,格式为
x,y
,其中
x
和
y
是起始和结束行号,且
x
必须在
y
之前。使用
;
代替
,
时,会先将当前行设置为
x
再解释
y
。
-
1,$
表示文件中的所有行。
常用的地址符号如下:
| 符号 | 用途 |
| ---- | ---- |
|
.
| 当前行 |
|
n
| 绝对行号 |
|
$
| 最后一行 |
|
%
| 所有行,等同于
1,$
|
|
x -/+ n
|
x
行之前或之后的第
n
行 |
|
- [n]
| 前
n
行 |
|
+ [n]
| 后
n
行 |
|
'x
| 标记为
x
的行 |
|
''
| 上一个上下文 |
|
/pat/
或
?pat?
| 向前或向后匹配到
pat
的行 |
以下是部分
ex
命令总结:
| 命令 | 用途 |
| ---- | ---- |
|
abbrev ab [string text]
| 定义输入
string
时自动转换为
text
,若未指定则列出所有缩写 |
|
[address] a [ ! ] text
| 在指定地址后追加文本,
!
标志可在输入文本时切换
autoindent
设置 |
|
args
| 打印参数列表成员,当前参数用方括号括起来 |
|
[address] c [ ! ] text
| 用
text
替换指定行,
!
标志可在输入文本时切换
autoindent
设置 |
|
[address] co destination
| 将指定地址的行复制到目标地址,
t
是
copy
的同义词 |
|
[address] d [bufSer]
| 删除指定地址的行,若指定
bufSer
,则将文本保存或追加到命名缓冲区 |
|
e [ ! ] [+n] file
| 开始编辑文件,
!
标志不警告未保存的更改,
+n
从第
n
行开始编辑 |
|
f [filename]
| 更改当前文件名,若未指定则打印文件当前状态 |
|
[address] g [ ! ] /pattern / [commands]
| 对包含
pattern
的所有行执行命令,若未指定命令则打印这些行,
!
标志对不包含
pattern
的行执行命令 |
|
[address] i [ ! ] text
| 在指定地址前插入文本,
!
标志可在输入文本时切换
autoindent
设置 |
|
[address] j [count]
| 将指定范围内的文本放在一行,调整空格 |
|
[address] k char
| 用
char
标记指定地址的行 |
|
[address] m destination
| 将指定地址的行移动到目标地址 |
|
n [ ! ] [ [+command] filelist]
| 编辑命令行参数列表中的下一个文件,使用
args
列出参数,若提供
filelist
则替换当前参数列表并开始编辑第一个文件,若指定
command
则在编辑第一个文件后执行 |
|
[address] nu [count]
| 打印指定行,并在每行前加上缓冲区行号,
#
可作为
number
和
nu
的缩写 |
|
[address] o [ /pattern/]
| 在指定地址或匹配
pattern
的行进入打开模式,用
Q
退出 |
|
P
| 保存当前编辑器缓冲区,就像系统崩溃时一样 |
|
[address] p [count]
| 打印指定行,并打印非打印字符 |
|
[address] pu [char]
| 从命名缓冲区恢复之前删除或复制的行到指定地址,若未指定
char
则恢复最后删除或复制的文本 |
|
q
| 终止当前编辑会话,若文件自上次更改后未保存或参数列表中有未访问的文件,需使用
!
标志才能退出 |
|
s [ ! ] [/pattern/rep/ options] [count]
| 将指定行中
pattern
的每个实例替换为
repl
,若省略
pattern
和
repl
则重复上次替换,支持
g
(替换所有实例)和
c
(每次更改前提示确认)选项 |
|
[address] r [ ! ] file
| 将文件内容复制到指定地址,若未指定文件则使用当前文件名 |
|
[address] r ! command
| 将命令的输出读入指定地址后的文本中 |
|
rec file
| 从系统保存区域恢复文件 |
|
rew [ ! ]
| 倒回参数列表并开始编辑第一个文件,
!
标志不警告未保存的更改 |
|
se parameter parameter2 ...
| 设置选项的值,若未提供参数则打印所有已更改的选项,布尔值选项可使用
option
或
nooption
,其他选项使用
option=value
语法 |
|
sh
| 创建新的shell,shell终止后继续编辑 |
|
so file
| 读取并执行文件中的命令 |
|
[address] t destination
| 将指定地址的行复制到目标地址 |
|
[address] ta tag
| 将编辑焦点切换到
tag
|
|
unabbreviate una word
| 从缩写列表中移除单词 |
|
undo U
| 撤销上一个编辑命令的更改 |
|
unmap unm char
| 从宏列表中移除
char
|
|
[address] v /pattern / [commands]
| 对不包含
pattern
的所有行执行命令,若未指定命令则打印这些行 |
|
ve
| 打印编辑器的当前版本号和最后更改日期 |
|
[address] vi [type] [count]
| 在指定地址进入可视模式,用
Q
退出,
type
可以是
-
、
"
或
.
,
count
指定初始窗口大小 |
|
[address] w [ ! ] [ [>>] file]
| 将指定行写入文件,若未指定地址则写入整个缓冲区内容,若未指定文件则保存到当前文件名,
>> file
表示追加到文件末尾,
!
标志强制覆盖文件现有内容 |
|
[address] w ! command
| 通过管道将指定行写入命令 |
|
wq [ ! ]
| 保存并退出文件 |
|
[address] ya [char] [count]
| 将指定行放入名为
char
的缓冲区,若未指定
char
则放入通用缓冲区 |
|
[address] z [type] [count]
| 打印以指定行为顶部的文本窗口,
type
可选,
count
指定显示的行数 |
|
[address] ! command
| 在shell中执行命令,若指定地址,则将地址中的行作为标准输入应用到命令,并将输出替换这些行 |
|
[address] =
| 打印指定行的行号 |
|
[address] < [count]
或
[address] > [count]
| 按指定方向移动指定行,左移(
<
)仅移动空格和制表符 |
|
address
| 打印指定地址的行 |
|
RETURN
| 打印文件中的下一行 |
|
[address] & [options] [count]
| 重复上一个替换命令 |
|
[address] - [count]
| 用替换命令中的上一个替换模式替换上一个正则表达式 |
mermaid流程图如下:
graph LR
A[进入ex] --> B[执行命令]
B --> C{命令类型}
C --> D[编辑命令]
C --> E[文件操作命令]
C --> F[打印命令]
C --> G[宏命令]
D --> B[继续执行其他命令]
E --> B
F --> B
G --> B
B --> H[退出ex]
sed编辑器
sed
编辑器的调用命令为:
sed [options] file(s)
,支持以下选项:
| 选项 | 用途 |
| ---- | ---- |
|
-n
| 仅打印
p
命令指定的行或
s
命令的
p
标志指定的行 |
|
-e cmd
| 下一个参数是编辑命令 |
|
-f file
| 下一个参数是包含编辑命令的文件 |
所有
sed
命令的通用形式为:
[address] [, address] [ ! ]command [arguments]
。
sed
会将输入的每一行复制到模式空间,指令由地址和编辑命令组成。若命令的地址与模式空间中的行匹配,则对该行执行命令;若命令没有地址,则对每一行输入执行命令。需注意,命令会影响模式空间的内容,后续命令的地址会尝试匹配模式空间中的行,而非原始输入行。
在
sed
命令中,地址可以是行号或用斜杠括起来的模式(
/pattern/
),指定两个地址时不能混合使用不同类型的地址。模式可使用正则表达式,
\n
可匹配模式空间中的换行符,但不包括模式空间末尾的换行符。若未指定模式,命令将应用于所有行;若只指定一个地址,命令将应用于第一个和第二个地址之间的所有行(包括这两行)。
!
操作符可使
sed
对不包含模式的所有行执行命令。多个命令可通过花括号分组:
[/pattern /] [, /pattern /] {
command1
command2
}
以下是
sed
命令的字母顺序列表:
| 命令 | 用途 |
| ---- | ---- |
|
: label
| 指定一个标签,供
b
或
t
命令跳转,标签最多包含八个字符 |
|
b
| 若有
[/pattern/]=
,则将匹配模式的每行的行号写入标准输出 |
|
[address] a\ text
| 在匹配地址的每行后追加文本,若文本跨多行,换行符前需加反斜杠,插入操作在遇到第一个未转义的换行符时结束,结果读入模式空间,编辑列表结束或命令明确打印模式空间时输出到标准输出 |
|
[address1] [, address2] b [label]
| 跳转到用
:
命令设置的标签,若未指定标签,则跳转到脚本末尾,即跳过后续编辑命令 |
|
[address1] [, address2] c\ text
| 用文本替换模式空间的内容,文本处理方式与
a
命令相同 |
|
[address1] [, address2] d
| 删除模式空间中的行,该行不输出到标准输出,读取新的输入行,从编辑列表的第一个命令开始继续编辑 |
|
[address1] [, address2] D
| 删除由
N
命令创建的多行模式的第一部分(直到嵌入的换行符)并开始编辑,若未对该行应用
N
命令,则与
d
命令相同 |
|
[address] [, address2] g
| 将保留空间(见
h
或
H
命令)的内容复制到模式空间,覆盖原有内容 |
|
[address1] [, address2] G
| 将保留空间的内容追加到模式空间的内容之后 |
|
[address1] [, address2] h
| 将模式空间的内容复制到保留空间,覆盖保留空间的原有内容 |
|
[address1] [, address2] H
| 将模式空间的内容追加到保留空间的内容之后,新旧内容用换行符分隔 |
|
[address1] i\ text
| 在匹配地址的每行前插入文本,文本处理方式与
a
命令相同 |
|
[address] [, address2] n
| 读取下一行输入到模式空间,当前行输出,但控制转移到下一个编辑命令,而非从编辑列表顶部开始 |
|
[address1] [, address2] N
| 将下一行输入追加到模式空间的内容之后,两行用嵌入的换行符分隔,该命令用于跨两行进行模式匹配 |
|
[address1] [, address2] p
| 打印指定的行,除非使用
-n
命令行选项,否则该命令会导致输出中该行重复,也用于命令改变控制流(
d
,
N
,
b
)的情况 |
|
[address1] [, address2] P
| 打印由
N
命令创建的多行模式的第一部分(直到嵌入的换行符),若未对该行应用
N
命令,则与
p
命令相同 |
|
[address] q
| 遇到指定地址时退出,先将指定行写入输出,并将之前
a
或
r
命令追加的文本一起输出 |
|
[address] r file
| 读取文件内容并追加到模式空间的内容之后,
r
和文件名之间必须有一个空格 |
|
[address1] [, address2] s/pattern/replacement/[flags]
| 将指定行中的
pattern
替换为
replacement
,若使用模式地址,
//
表示最后指定的模式地址。支持以下标志:
g
(替换每行中
/pattern/
的所有实例)、
p
(成功替换时打印该行)、
w file
(替换成功时将该行写入文件,最多可打开十个不同的文件) |
|
[address1] [, address2] t [label]
| 测试指定行是否有成功的替换,若有则跳转到标签,若未指定标签,则跳到编辑命令列表的底部 |
|
[address1] [, address2] w file
| 将模式空间的内容写入文件,该操作在遇到命令时执行,而非模式空间输出时,
w
和文件名之间必须有一个空格,最多可打开十个不同的文件 |
|
[address1] [, address2] x
| 交换模式空间和保留空间的内容 |
awk程序
awk
程序由模式和过程组成:
pattern {procedure}
,两者都是可选的。若缺少
pattern
,则对所有行应用
{procedure}
;若缺少
{procedure}
,则将行原样输出到标准输出。
每个输入行(记录)会根据空白字符(空格或制表符)或用户定义的记录分隔符分割成字段,字段可通过变量
$1, $2, ..., $n
引用,
$0
表示整个记录。
模式可以使用正则表达式,此外还有以下规则:
-
BEGIN
模式允许指定在处理第一行输入之前执行的过程,通常用于设置全局变量。
-
END
模式指定在处理最后一行输入之后执行的过程。
-
^
和
$
可分别引用字段的开头和结尾,而非行的开头和结尾。
- 模式可以是使用关系运算符(
<
,
<=
,
==
,
!=
,
>=
,
>
)的关系表达式,比较可以是字符串或数值比较。
- 模式可以使用布尔运算符(
||
- 或,
&&
- 与,
!
- 非)组合。
- 模式可以包含预定义变量,如
NF > 1
可选择包含多个字段的记录。
以下是一些预定义变量:
| 变量 | 用途 |
| ---- | ---- |
|
FS
| 字段分隔符,默认为空格和制表符 |
|
RS
| 记录分隔符,默认为换行符 |
|
OFS
| 输出字段分隔符,默认为空格 |
|
ORS
| 输出记录分隔符,默认为换行符 |
|
NR
| 当前记录的编号 |
|
NF
| 当前记录中的字段数 |
|
$0
| 整个输入记录 |
|
$1, $2, ..., $n
| 当前记录中的第一个、第二个、…、第n个字段,字段由
FS
分隔 |
过程由一个或多个命令、函数或变量赋值组成,用换行符或分号分隔,包含在花括号内。命令可分为以下四类:
- 变量或数组赋值
- 打印命令
- 内置函数
- 控制流命令
以下是
awk
的一些命令总结:
| 命令 | 用途 |
| ---- | ---- |
|
for (i=lower; i<=upper; i++) command
| 当变量
i
的值在
lower
和
upper
之间时,执行命令,一系列命令需放在花括号内,可使用
<=
或其他关系运算符,
++
或
--
可用于变量增减 |
|
for i in array command
| 对于数组
array
中的每个变量
i
,执行命令,一系列命令需放在花括号内 |
|
if (condition) command [else] [command]
| 若条件为真,则执行命令,否则执行
else
子句中的命令,条件可以是使用关系运算符或模式匹配运算符的表达式,一系列命令需放在花括号内 |
|
x = length(arg)
| 返回
arg
的长度,若未提供
arg
,则默认为
$0
|
|
x = log(arg)
| 返回
arg
的对数 |
|
print [args]
| 在输出中打印参数,参数通常是一个或多个字段,也可以是预定义变量,文字字符串需用引号括起来,参数在参数列表中用逗号分隔时,输出中用
OFS
指定的字符分隔,用空格分隔时则直接连接 |
|
printf "format, "expression(s)
| 格式化打印语句,根据
format
参数的指令格式化字段或变量,参数数量必须与
format
部分指定的数量一致,格式遵循C语言的
printf
语句约定,可包含转义序列,若有多个表达式要打印,需指定多个格式 |
|
x = split(string, array [, sep])
| 将字符串
string
按分隔符
sep
分割成数组
array
的元素,若未指定
sep
,则使用
FS
,返回创建的数组元素数量 |
|
x = sprintf("format", expression)
| 根据指定的格式返回表达式的值 |
|
x = sqrt(arg)
| 返回
arg
的平方根 |
|
x = substr(string,m, [n])
| 返回字符串
string
从第
m
个字符开始的子字符串,若指定
n
,则包含接下来的
n
个字符,若未指定
n
,则包含到字符串末尾的所有字符 |
|
while (condition) command
| 当条件为真时执行命令,条件的允许情况与
if
命令相同,一系列命令需放在花括号内 |
mermaid流程图如下:
graph LR
A[开始] --> B[读取输入行]
B --> C{匹配模式?}
C -->|是| D[执行过程]
C -->|否| B[读取下一行]
D --> B[读取下一行]
B --> E{是否最后一行?}
E -->|否| B[继续读取]
E -->|是| F[结束]
综上所述,掌握这些UNIX文本处理工具和命令,能够帮助用户更高效地进行文本编辑、处理和文档制作,满足不同场景下的需求。通过合理运用这些工具,可大大提高工作效率和质量。
超级会员免费看
142

被折叠的 条评论
为什么被折叠?



