# 修改文本
# tr
tr <源字符集> <目标字符集> # 替换文本中的指定字符
-c # 反选源字符集(即选中其它字符)
-d # 删除源字符集
- tr 命令的输入不能是文件,只能是 stdin ,且输出到 stdout 。
- 例:
cat f1 | tr a-z A-Z # 将小写字母换成大写字母
# sed
sed [expression] [file]... # 读取文件内容,根据表达式进行修改,然后输出
-e # 读取 stdin
-i # 将修改结果输出到源文件(否则默认输出到 stdout )
-n # --quiet ,取消默认输出,此时使用 p 等命令才会有输出
表达式示例:
# 处理指定行 -n '1p' # 只显示第 1 行 -n '1,5p' # 只显示第 1~5 行 '1,$d' # 删除第 1 行至最后一行(使用单引号作为定界符,避免将 $ 当做对变量取值),然后输出剩下的内容 '1,4d;6d;$d' # 删除第 1~4 行、第 6 行、最后一行(用 ; 分隔多个目标) '1i hello' # 在第 1 行之前插入一行字符串 '1a hello' # 在第 1 行之后插入一行字符串 'a hello' # 在每行之后插入一行字符串 # 使用正则匹配 -n '/hello/p' # 找到正则匹配的每行并显示,相当于 grep 命令。如果不加 -n ,则会将原始文本也输出 '/hello/d' # 找到正则匹配的每行并删除 # 使用正则替换 's/源字符串/目标字符串/g' # 替换字符串,源字符串采用基本正则语法 's#^hello#hi#g' # s 之后的第一个字符会被视作分隔符 's#hello##g' # 目标字符串为空,则会删除源字符串 's#hello##2' # 只替换第二次 's#hello \(\w*\)#\1#g' # 可以按 \1 的格式提取正则匹配的元素组 '3 i Hello' # 插入一行内容,作为第 3 行 '0,/^hello/s##Hello#' # 只执行一次正则替换
- sed 正则表达式的特点:
- 大部分元字符需要加上 \ 转义,除了
^$.*[]
。 - 支持 \w、\s 及相反字符集,不支持 \d 字符集。
- 大部分元字符需要加上 \ 转义,除了
- sed 正则表达式的特点:
例:
cat f1 | sed 's#hello##g' > f2 # 将修改结果保存到另一个文件 sed -i 's#hello##g' f1 # 将修改结果保存到源文件
[root@CentOS ~]# echo 'Hello World' | sed 's#Hello#Hi#g' Hi World [root@CentOS ~]# echo 'Hello World' | sed 's#Hello \(\w*\)#\1#g' World
sed -i 's#first_line#Hello\ World\ first_line#g' f1 # 插入多行
用 sed -i 命令修改文件时,会在源文件的同一目录下,创建一个名为
sed${random_id}
的临时文件,用于暂存修改结果。- 等修改完全部内容,会自动删除源文件,然后将临时文件重命名为源文件,导致源文件的 inode 变化。
- 如果不想改变 inode ,则可以将修改结果保存到另一个文件,然后拷贝文件内容到源文件。例如:不过这样需要临时占用两倍磁盘空间。
sed 's#hello##g' f1 > f2 cat f2 > f1
# vim
vi 是类 Unix 系统的内置文本编辑器,而 vim 是一个流行的类 vi 编辑器,功能更多。
同类软件:
- nano :一个比 vi 功能更简单的文本编辑器。
- less :一个只读的文本阅读器。
- 用 vi/vim 打开一个文件时,会将整个文件的内容加载到内存中,并扫描每行内容,进行语法突出显示。因此打开文件时有一定耗时,占用内存比整个文件的体积还大一些。
- 使用 less 时,只会将文件的部分内容加载到内存中,比如只加载第 100~200 行的内容,显示给用户看,因此占用的内存很少。
- 因此 vi/vim 只适合打开低于 100MB 的文件。阅读大型文件时,建议用 less 命令。修改大型文件时,建议用 sed 命令。
执行以下命令即可启动 vim 编辑器:
vim [path]
- 如果不指定 path ,则会打开一个空的编辑器界面。
- 如果指定的 path 是一个文件,则对它进行编辑。如果该文件不存在,则可以在保存时创建它。
- 如果指定的 path 是一个目录,则可以管理该目录下的文件。
# 命令模式
启动 vi/vim 时,默认进入命令模式(Command mode):
- 此时不能编辑文本,只能输入键盘上的某些字符作为命令(区分大小写)。
- 文本末尾显示的
~
表示空行,并不是实际存在的字符。 - vi/vim 的命令支持组合,可以连续输入多条命令,组合它们的功能。
- 比如输入一个数字 n 之后再输入 dd ,会连续剪贴 n 行。
- 关于切换模式的命令:
i/a
:进入插入模式。o
:在光标下方插入一行并进入插入模式。r
:替换光标所在的那个字符。R
:进入替换模式。- 输入以
:
、/
、?
开头的字符串会进入底线命令模式。 - 进入其它模式之后,按
Esc
或Ctrl + c
即可退出到命令模式。
- 关于移动光标的命令:
PageUp
或PageDown
:向上或下翻页。k
、j
、h
、l
:将光标向上、下、左、右移动一格。Space
:将光标后移一格。Enter
:将光标下移一行。gg
:将光标移动到第一行。G
:将光标移动到最后一行。- 输入
/word
(或?word
)会向下(或向上)查找 word 字符串,然后输入 n(或 N)会切换到下一个(或上一个)匹配结果。
- 关于撤销的命令:
u
:撤销上一次对文件内容的修改操作。Ctrl + r
:重做被撤销的操作。.
:重做上一次操作(对 u 和 Ctrl + r 无效)。
- 关于复制粘贴的命令:
yy
:复制光标所在的当前行。x
或X
:删除光标之后或之前的一个字符。dd
:剪贴当前行。p
或P
:粘贴到下一行或上一行。v
:开始选中,此时光标移动过的区域都会被反白选中,然后输入 d 或 y 即可删除或复制。Ctrl + v
:开始矩形选中。
# 底线命令模式
底线命令模式(Last line mode):
此时输入的字符会显示在下方的命令行中。
常用命令:
:wq
:保存并退出(输入 w 表示保存,输入 q 表示退出):wq!
:强制保存再退出(输入!表示强制执行操作):wq [文件名]
:保存为指定文件。:s/源字符串/目标字符串/g
:在当前行替换字符串。(目标字符串为空的话就是删除):%s/源字符串/目标字符串/g
:在每一行替换字符串。:set nu
:显示行号。/str
:向下查找字符串。然后输入 n(或 N)会切换到下一个(或上一个)匹配结果。?str
:向上查找字符串。
执行
:set xxx
可临时修改 vim 的配置参数,也可以将配置参数永久保存到/etc/vimrc
或~/.vimrc
文件。常见的配置参数:
set encoding=utf-8 " 设置编码格式 set number " 显示行号 set nonumber " 不显示行号 set ignorecase " 搜索时不区分大小写 set paste " 进入粘贴模式,使粘贴的文本内容会原样地输入 vim set nopaste " 退出粘贴模式 set tabstop=4 " 每个制表符 \t 显示的宽度 set expandtab " 按下 Tab 键时,输入空格而不是制表符
- 用双引号 " 声明单行注释。
# 交换文件
用 vi/vim 命令打开文件时(即使未修改),会在源文件的同一目录下(而不是执行命令的目录),创建一个名为
.filename.swp
的交换文件。- 交换文件记录了源文件的原始内容、用户每次修改的增量内容,从而允许用户撤销操作、重做操作。
- 交换文件会比源文件的体积更大一些。
- 退出 vi/vim 时,会自动删除交换文件。
执行
:w
保存文件时(即使未修改),vi/vim 会将当前内容保存到源文件。根据配置参数 backupcopy 取值的不同,有几种保存方式:backupcopy=yes
- 原理:根据交换文件,得到文件的修改结果,保存为一个名为
filename~
的备份文件。然后拷贝备份文件的内容,覆盖式写入源文件。最后删掉备份文件。 - 优点:源文件的 inode 不变,文件属性不变。
- 缺点:如果文件体积大,则拷贝需要一定耗时。如果同时有其它程序在修改源文件,则可能出错。
- 原理:根据交换文件,得到文件的修改结果,保存为一个名为
backupcopy=no
- 原理:先创建一个备份文件,并将它的文件属性改成跟源文件一致。然后删除源文件,将备份文件重命名为源文件。
- 优点:几乎没有耗时。
- 缺点:
- 源文件被删了,创建新文件,inode 变化。
- 新文件的文件属性可能不一致,比如当前用户无权修改某个属性。
- 如果源文件是一个软链接,则新文件会是一个普通文件。
backupcopy=auto
- 原理:自动判断。优先采用 no 方式,如果遇到以下情况,则采用 yes 方式:
- 源文件是软链接。
- 源文件的文件属性不能全部复制到新文件。
- 默认配置了
backupskip=/tmp/*
,表示修改该路径下的文件时,不会创建备份文件。
- Unix 系统的 vi/vim 默认采用 yes 方式,而大部分 Linux 发行版的 vi/vim 采用 auto 方式。
- 原理:自动判断。优先采用 no 方式,如果遇到以下情况,则采用 yes 方式:
用 vi/vim 打开一个文件时,可能遇到这种报错:
Swap file ".f1.swp" already exists! [O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:
该报错表示该文件已存在交换文件,可能是因为:
- 此时有其他用户正在用 vi/vim 打开该文件,而一个文件同时只允许被一个 vi/vim 进程修改。
- 之前某个用户用 vi/vim 打开了该文件,但 vi/vim 进程异常退出,没有自动删除交换文件。此时可执行以下命令:
vim -r .filename.swp # 恢复到文件的最后修改状态 :wq # 保存文件 rm -f .filename.swp # 删除交换文件
# iconv
iconv [file] # 转换文本文件的编码格式(默认输出到 stdout)
-f utf-8 # 源文件的编码格式
-t gbk # 要转换成的编码格式
-c # 忽略转换失败的字符
- 例:批量转换文件的编码格式
file_list=`find . -name "*.txt"` from_encoding='utf-8' to_encoding='gbk' for f in $file_list do iconv $f -f utf-8 &> /dev/null if [ $? ]; then echo "Convert the encoding of file $f to $to_encoding" iconv $f -f $from_encoding -t $to_encoding > .iconv.tmp mv .iconv.tmp $f else echo "The encoding of file $f is not $from_encoding , skip." continue fi done