Linux文件格式化与相关处理及sed工具

http://blog.csdn.net/pipisorry/article/details/52564957

geditor, sed, ed, awk, Emacs

文本处理工具

[Linux Shell 文本处理工具集锦]

geditor

最常用的类似windows下的记事本

ubuntu16.04 gedit乱码问题解决

gsettings set org.gnome.gedit.preferences.encodings candidate-encodings "['CURRENT', 'UTF-8', 'GB18030', 'ISO-8859-15', 'UTF-16']"

Note:

1 顺序要像上面那样,否则还是打开乱码。如将gbk18030放在utf-8前面打开utf-8就会出乱码。

2 其值的设置可以通过安装dconf-editor查看和修改。终端输入dconf-editor命令。

皮皮blog

sed工具-使用 sed 进行编辑

本文讨论的最复杂和最强大的编辑工具是 sed(流编辑器)。它是一个文本编辑器,但是与诸如 ed 等文本编辑器不同,它编辑输入流并写到输出流。因此,它对于编辑命令输出或对于使用其他工具对文件进行预处理非常有用——然后您可以将该文本通过管道直接输出给 sed,以进行快速编辑。但是 sed 还可以操作文件,并且其脚本语言具有高级模式匹配功能,因此它是用于执行任何类型的快速文本编辑的理想选择——例如对一组文件进行快速搜索和替换。事实上,它是现有用于文本编辑的最流行命令行工具之一。

sed 接受包含任何数量命令的脚本,后面跟着可选的指定输入文件的选项;缺省情况下,它读取标准输入。某些版本的 sed 有一个 -i 选项,此选项指定应该编辑的输入文件。(如果没有此选项,则读取输入文件,而不对其执行写入。)如果您安装的版本支持此选项,则应该使用它——它允许您使用单个命令对任何指定的文件执行快速编辑操作。

sed -i script filespec

以下示例假设您的 sed 支持 -i 选项。否则,您必须使用 Shell 重定向将输出保存到新文件,并在另一个步骤将新文件重命名为旧文件,从而执行临时文件中转:

sed script file > newfile; mv newfile file

对于多个文件,您必须执行循环:

for i in *; { sed script $i > $i.new; mv $i.new $i; }

定界符

sed命令中字符 / 在sed中作为定界符使用,也可以使用任意的定界符:

sed 's:test:TEXT:g'

sed 's|test|TEXT|g'

定界符出现在样式内部时,需要进行转义: sed 's/\/bin/\/usr\/local\/bin/g'

sed的命令行中引用shell变量Passing arguments into a sed script

直接使用$符号会被当成正则表达式,会出错:sed: -e expression #1, char 69: unknown option to `s'、

方法1:(lz推荐,修改写界符)

如果$app中没有/字符可以直接这样:sed "s:example:$app:g"

export ycm_path_to_python_interpreter='/usr/bin/python3'

sed 's:ycm_path_to_python_interpreter=.*:ycm_path_to_python_interpreter='$ycm_path_to_python_interpreter':g' vim_config/plugin_config | grep ycm_path

方法2:

#export ycm_path_to_python_interpreter="'~\/ENV\/ubuntu_env\/bin\/python'"

sed 's/ycm_path_to_python_interpreter=.*/'ycm_path_to_python_interpreter=$ycm_path_to_python_interpreter'/g' vim_config/plugin_config | grep ycm_path

Passing a word into a shell script that calls sed is easy if you remembered my tutorial on the UNIX quoting mechanism. To review, you use the single quotes to turn quoting on and off. A simple shell script that uses sed to emulate grep is:
#!/bin/sh
sed -n 's/'$1'/&/p'
However - there is a problem with this script. If you have a space as an argument, the script would cause a syntax error A better version would protect from this happening:
#!/bin/sh
sed -n 's/'"$1"'/&/p'
还要注意的是,替换的新值$val中不能包含/,否则出错一样,但是可以使用\/来进行转义就可以了。

如果要想替换的新值$val中包含‘’,那么要使用export val="''",双引号包裹''。

[Sed - An Introduction and Tutorial by Bruce Barnett]

替换

全面替换标记g

使用后缀 /g 标记会替换每一行中的所有匹配:
sed 's/book/books/g' file
当需要从第N处匹配开始替换时,可以使用 /Ng:
echo sksksksksksk | sed 's/sk/SK/2g'
skSKSKSKSKSK
echo sksksksksksk | sed 's/sk/SK/3g'
skskSKSKSKSK

全局替换和首次替换

With no flags, the first matched substitution is changed.With the"g" option, all matches are changed.If you want to modify a particular pattern that is not the first one onthe line, you could use "\(" and"\)" to mark each pattern, and use"\1" to put the first pattern back unchanged. This next examplekeeps the first word on the line but deletes the second:

sed 's/\([a-zA-Z]*\) \([a-zA-Z]*\) /\1 /' <old >new

Yuck. There is an easier way to do this. You can add a number after thesubstitution command to indicate you only want to match that particularpattern. Example:

sed 's/[a-zA-Z]* //2' <old >new

You can combine a number with the g (global) flag. For instance, if you want to leave the first word alone, but change the second, third, etc. to be DELETED instead, use /2g:

sed 's/[a-zA-Z]* /DELETED /2g' <old >new

整行首次替换sed 's/old/new/2'或者sed 's/old/new/3+'

整行的全局替换sed 's/old/new/g'或者sed 's/old/new/g'  g 表示行内全面替换。

[/1, /2, etc. Specifying which occurrence]

删除操作:d命令
删除空白行:
 
# sed '/^$/d' file
删除文件的第2行:
 
# sed '2d' file
删除文件的第2行到末尾所有行:
 
# sed '2,$d' file
删除文件最后一行:
 
# sed '$d' file
删除文件中所有开头是test的行:
 
# sed '/^test/'d file
2.5 已匹配字符串标记&
正则表达式 w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词:
 
# echo this is a test line | sed 's/w+/[&]/g'
[this] [is] [a] [test] [line]
所有以192.168.0.1开头的行都会被替换成它自已加localhost:
 
# sed 's/^192.168.0.1/&localhost/' file
192.168.0.1localhost
2.6 子串匹配标记1
匹配给定样式的其中一部分:
 
# echo this is digit 7 in a number | sed 's/digit ([0-9])/1/'
this is 7 in a number
命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,(..) 用于匹配子串,对于匹配到的第一个子串就标记为 1,依此类推匹配到的第二个结果就是2,例如:
 
# echo aaa BBB | sed 's/([a-z]+) ([A-Z]+)/2 1/'
BBB aaa
love被标记为1,所有loveable会被替换成lovers,并打印出来:
 
# sed -n 's/(love)able/1rs/p' file
2.7 组合多个表达式
 
# sed '表达式' | sed '表达式'
等价于:
# sed '表达式; 表达式'
2.8 引用
sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号。
 
test=hello
echo hello WORLD | sed "s/$test/HELLO"
HELLO WORLD
2.9 选定行的范围:,(逗号)
所有在模板test和check所确定的范围内的行都被打印:
 
# sed -n '/test/,/check/p' file
打印从第5行开始到第一个包含以test开始的行之间的所有行:
 
# sed -n '5,/^test/p' file
对于模板test和west之间的行,每行的末尾用字符串aaa bbb替换:
 
# sed '/test/,/west/s/$/aaa bbb/' file
2.10 多点编辑:e命令
-e选项允许在同一行里执行多条命令:
 
# sed -e '1,5d' -e 's/test/check/' file
上面sed表达式的第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
和 -e 等价的命令是 –expression:
 
# sed --expression='s/test/check/' --expression='/love/d' file
2.11 从文件读入:r命令
file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面:
 
# sed '/test/r file' filename
2.12 写入文件:w命令
在example中所有包含test的行都被写入file里:
 
# sed -n '/test/w file' example
2.13 追加(行下):a命令
将 this is a test line 追加到 以test 开头的行后面:
 
# sed '/^test/athis is a test line' file
在 test.conf 文件第2行之后插入 this is a test line:
 
# sed -i '2athis is a test line' test.conf
2.14 插入(行上):i命令
将 this is a test line 追加到以test开头的行前面:
 
# sed '/^test/ithis is a test line' file
在test.conf文件第5行之前插入this is a test line:
 
# sed -i '5ithis is a test line' test.conf
2.15 下一个:n命令
如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续:
 
# sed '/test/{ n; s/aa/bb/; }' file
2.16 变形:y命令
把1~10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令:
 
# sed '1,10y/abcde/ABCDE/' file
2.17 退出:q命令
打印完第10行后,退出sed
 
# sed '10q' file
2.18 保持和获取:h命令和G命令
在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。
 
# sed -e '/test/h' -e '$G' file
在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
2.19 保持和互换:h命令和x命令
互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换:
 
# sed -e '/test/h' -e '/check/x' file
2.20 脚本scriptfile
sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
 
# sed [options] -f scriptfile file(s)
2.21 打印奇数行或偶数行
方法1:
 
# sed -n 'p;n' test.txt  #奇数行
# sed -n 'n;p' test.txt  #偶数行
方法2:
 
# sed -n '1~2p' test.txt  #奇数行
# sed -n '2~2p' test.txt  #偶数行
2.22 打印匹配字符串的下一行
 
# grep -A 1 SCC URFILE
# sed -n '/SCC/{n;p}' URFILE
# awk '/SCC/{getline; print}' URFILE

[sed命令]

展示如何将文件内容读入到sed输出,同时包含如何将一个文件的部分内容写入到另一文件

一.文件读取

假定有两个文件,file1和file2,内容分别如下:

$ cat file1
1apple
1banana
1mango
$ cat file2
2orange
2strawberry

sed有两个选项用来读写文件

r filename : 读取filename指定的文件内容
w filename : 将内容写入filename指定的文件

看例子:

1.在file1的每一行读完之后读取file2的内容

$ sed ‘r file2’ file1
1apple
2orange
2strawberry
1banana
2orange
2strawberry
1mango
2orange
2strawberry

r file2读取file2的所有内容,因此r之前没有知道那个行号或匹配,因此有了上面的输出,记住,sed的工作机制,每次读file1的一行,然后执行命令

2.如何在读取了file1的第一行之后将file2读入

$ sed ‘1r file2’ file1
1apple
2orange
2strawberry
1banana
1mango

r前面加个1就行了

3.当file1某行匹配了模式之后,读入file2

$ sed ‘/banana/r file2’ file1
1apple
1banana
2orange
2strawberry
1mango

sed逐行读入file1,然后判断该行是否匹配banana,如果匹配,就读入file2

4.当file1读取完成后读入file2,其实就是合并两个文件

$ sed ‘$r file2’ file1
1apple
1banana
1mango
2orange
2strawberry

这里只是演示一下,其实cat file1 file2就可以完成合并。

批量删除文件中的注释

sed -i 's|^#.*||g' *.cpp p360

[Unix sed实用教程系列目录 译自awk-sed@theunixschool]

[Unix sed实用教程开篇

皮皮blog

使用 ed 命令进行编辑

顾名思义,行编辑器 ed 对输入文件的行执行编辑。它将整个文件读入自己的缓冲区,对该副本执行指定的操作,并可选地将缓冲区写到磁盘。您可以在编辑操作中指定任何数量的行,并且这些操作可以在一个序列中进行组合和指定。这些事实使得 ed 成为在脚本中使用的理想选择。以如下格式指定操作:

[address]command [text]

address 指定要处理的一行或多行(缺省为当前行),并且可以通过多种方式进行指定。单字符的 command 是要对指定行执行的操作。对于脚本中的特别单命令行程序,可以使用 echo 将一组命令和文本管道传输给 ed,从而以非交互式的方式使用它。

( echo 'OPERATION'; echo 'OPERATION';
... echo 'wq' ) | ed -s FILENAME

如果在操作中输入文本,应该回显一个句点 (.) 来指示输入结束。最后的 wq 写入文件并退出。-s 选项使 ed 静默地操作,并禁止所有正常输出。

幸运的是,ed 的基本寻址方法和命令是相当标准化的。表 2 描述了主要的寻址形式。表 3 给出了命令。

表 2. 在 ed 中对行寻址
选项 描述
. 此选项对当前行寻址(缺省地址)。
number 此选项对第 number 行寻址。可以按逗号分隔的范围 (first,last) 对行寻址。0 代表缓冲区的开头(第一行之前)。
-number 此选项对当前行之前的第 number 行寻址。如果没有 number,则减号对紧跟在当前行之前的行寻址。
+number 此选项对当前行之后的第 number 行寻址。如果没有 number,则加号对紧跟在当前行之后的行寻址。
$ 此选项对最后一行寻址。
, 此选项对第一至最后一行寻址,包括第一行和最后一行(与 1,$ 相同)。
; 此选项对当前行至最后一行寻址。
/pattern/ 此选项对下一个包含与 pattern 匹配的文本的行寻址。
?pattern? 此选项对上一个包含与 pattern 匹配的文本的行寻址。
表 3. 主要的 ed 命令
命令 描述
a 此命令在指定的地址之后追加文本。
c 此命令将指定的地址更改为给定的文本。
d 此命令删除指定地址处的行。
i 此命令在指定的地址之前插入文本。
q 此命令在将缓冲区保存到磁盘后终止程序并退出。
r file 此命令读取 filespec 的内容并将其插入指定的地址之后。
s/pattern/replacement/ 此命令将匹配 pattern 的文本替换为指定地址中的 replacement 文本。
w file 此命令将指定的地址写到 file。如果没有 address,则此命令缺省使用整个缓冲区。

linux将一个文件2插入到另一个文件1首行

直接使用cat 2 1 > 1会报错:cat: 1: input file is output file

而使用cat 2 >> 1是将2append到1结尾

解决:

(echo '0r 2'; echo 'wq') | ed -s 1

或者

(echo '0a'; cat 2; echo '.'; echo 'wq') | ed -s 1

在文件开头插入文本,第二部分
通过可在脚本中使用的 ed 单命令行程序,您可以容易地在文件开头插入文本。插入操作是使用 ed 并通过 a 命令将给定文本追加到第 0 行(文件开头)来完成的:
$ cat file
This is the end.
$ (echo '0a'; echo 'This is the beginning.'; echo '.'; echo 'wq') | ed -s file
$ cat file
This is the beginning.
This is the end.
$
您可以交互式地完成同样的任务:
$ cat file
This is the end.
$ ed -s file
> 0a
> This is the beginning.
> .
> wq
$ cat file
This is the beginning.
This is the end.
$
若要在文件开头插入另一个文件的内容,可以使用 r 命令:
$ (echo '0r headnotes'; echo 'wq') | ed file

[使用命令行高效地进行文本编辑 使用 cat、ed 和 sed 的快速编辑示例]

皮皮blog

文件的格式化与相关处理

格式化打印:printf

awk:好用的数据处理工具

相比于sed常常用于一整行的处理,awk更倾向于将一行分成数个字段来处理。因此,awk相当适合小型的数据处理。

awk 通常运行的模式

$ awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
awk 后面接两个单引号并加上大括号 {} 来设置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个指令的 standard output 。
awk 主要是处理“每一行的字段内的数据”,而默认的“字段的分隔符号为 "空白键" 或 "[tab]键" ”!
$ last -n 2
dmtsai   pts/0     192.168.1.100   Tue Jul 14 17:32   still logged in
dmtsai   pts/0     192.168.1.100   Thu Jul  9 23:36 - 02:58  (03:22)
想要取出帐号与登陆者的 IP ,且帐号与 IP 之间以 [tab] 隔开
$ last -n 2 | awk '{print $1 "\t" $3}'
dmtsai  192.168.1.100
dmtsai  192.168.1.100
整个 awk 的处理流程是:
    读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
    依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
    做完所有的动作与条件类型;
    若还有后续的“行”的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
那么 awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要

awk 的内置变量

变量名称     代表意义
NF     每一行 ($0) 拥有的字段总数
NR     目前 awk 所处理的是“第几行”数据
FS     目前的分隔字符,默认是空白键
如果我想要:
    列出每一行的帐号(就是 $1);
    列出目前处理的行数(就是 awk 内的 NR 变量)
    并且说明,该行有多少字段(就是 awk 内的 NF 变量)
$ last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}'
。。。

文件比较工具:diff cmp patch

文件打印准备:pr

皮皮blog

Emacs文件编辑软件

Emacs是一个扩展方便,定制能力强,文档丰富的动态交互编辑器。Emacs的核心构建在Emacs Lisp解释器之上,其中Emacs Lisp是大部分Emacs的内建函数和拓展模块的实现语言。Emacs可以在命令行界面下(CLI)工作良好,在图形界面系统下,使用GTK作为默认的图形界面构建工具。在文本编辑能力上,Emacs常常拿来和vim比较。

[Emacs (简体中文)]

from: http://blog.csdn.net/pipisorry/article/details/52564957

ref: [linux中shell截取字符串方法总结]

上一篇:SQL语法基础之INSEART语句


下一篇:VBS基础篇 - 循环语句(3) - For...Next