Unix/Linux Shell编程实战:使用嵌入文档Here Documents

一、Here Documents(嵌入文档)
Here Documents作为重定向的一种方式,指示shell从源文件的当前位置开始读取输出,直到遇到只包含一个单词的文本行时结束。在该过程中读到的所有文本行都将作为某一个命令的标准输入而使用。
       here-documents的使用形式:

command <<[-] limit_string
         msg_body
limit_string

如果用双引号或单引号将”limit_string”引用起来或用转义符\将其转义,则here-document中的文本将不被扩展,即参数替换被禁用。否则,here-document中的所有文本都将进行常规的参数扩展、命令替换、表达式计算。在后一种情况下,字符序列\<newline>将被忽略, 并且必须对元字符\, $, 和`使用\进行转义。

如果用<<而不是<<-,则后面的limit_string必须位于行首,否则,若here_document用在函数内部,则会报语法错误;用在函数外面,其后面的所有内容均会被当做here_document的内容。

如果重定向操作符是<<-, msg_bodylimit_string行中的所有前缀TAB字符都将被忽略(但空格不会被忽略)。这样源代码中的here-documents就可以按照优雅的嵌入方式进行对齐。

二、技术的应用
         下面我们考察一下在Shell脚本中使用Here Documents的必要性所在。Shell脚本对于文本文件的处理是非常方便的,因此实现本文所要完成的工作还是比较简单的,只需对所有文件进行一次循环过程。但是问题在于,从①-②,②-③的每一部,实际上都是使用cut、echo、cat等进行流处理,每个处理过程的输出作为下一步骤的输出。这里面自然的要使用重定向的方法。在以前对BASH用的不熟的时候,往往笨拙的使用临时文件存储这些中间结果。比如: 00000004.REG -> 00000004.cut -> 00000004.line -> all.txt。这样处理的过程中,代码显的非常杂乱,而且有时候不得不写出多个脚本来处理重定向,这种情况使得问题更为加重。
        因此,这次下决心要将代码写的精简一些。在BASH内部可以使用Here Documents进行重定向,使流的输入输出都是在同一脚本内进行的,不用拆开成多个脚本,也省略了大量的中间文件,使代码非常清晰、紧凑。

Here Documents的一般形式如下:
0001 commands <<ID
0002     here documents
.......     ......
000n ID<\n>
        在上面这个语法描述中,0001行的commands是任何SHELL命令。ID是一个字符串标识,标志着嵌入文档的开始(习惯上,常用的标识是EOF,等等)。从0002行可以写任何文本,这里写入的内容都将作为标准输入传送给commands。在最后一行写标识符ID,代码嵌入文本结束。

在使用Here Documents编写脚本的时候注意以下两点:

在000n行上,必须只有一个ID,也就是说,ID前面不能有空格,ID后面必须是回车符。否则SHELL处理时会出错。这一点在实际时要尤为注意。

当使用 <<- 时, 输入行和000n行上的ID前的任何TAB字符将会被忽略;

嵌入文档内可以写普通文本(比如说,写程序的使用Usage),也可以是标准的SHELL语句。如果是SHELL语句,要使用反引号(`)括起来,这时候语句的标准输出也将作为嵌入文档送给commands。这个特性非常有用。

  1. 1.    cat用法
    [exam@Exam-Server user]$ cat aa.sh
         1 #!/bin/bash
         2
         3 cat <<EOF # cat > file << EOF,则输出到新文件中,而不是stdout
         4    Now:
         5    `date`
         6 EOF
    [exam@Exam-Server user]$ sh aa.sh
    Now:

可以将here_document的输出保存到文件或变量中

variable=$(cat << EOF

This varibale

runs over multiple lines.

EOF)

echo $variable

This varible runs over mutiple lines.

可以用匿名的命令来接收here_document的输出,该技术可以用来注释掉代码块。

: << EOF

${HOSTNAME?}${USER?}${MAIL?} # 如果其中一个变量没被设置, 那么就打印错误信息.

EOF

 

三 7月 26 19:23:24 CST 2006

上面是一个最简单的例子,但是已经基本概括了Here Documents的使用方法。在aa.sh中,EOF作为嵌入文档的标识ID。4、5行中的Here Documents是一行标准文本“Now”和一个命令date的输出。两部分输出送给了cat命令去执行。

2.shell编辑文件

shell编辑文件最常用的方法就是echo 字符串 >> 文件。但是要删除一行怎么办?Here Document就搞定了。

经Jeremiah测试,在Here Document中使用vi是不行的。替代方法是使用ed命令。在命令行执行以下:

$ touch base.txt
$ ed base.txt
a
this is line1.
this is line2.
this is line3.
this is line4.
.
wq

先新建一个文件base.txt,然后ed这个文件,输入a表示最后追加,输入了四行文字。.表示结束输入。wq表示保存退出。

那我们再用ed命令,在shell脚本里面对这个文件再次进行操作。如下。

#!/bin/sh
ed base.txt << EOF
3 # 到第3行
d # 删除该行
i # 本行增加
this is line 3 new.  # 新行内容
.  # 结束
w
q # wq表示保存
EOF

执行的结果如下所示。

$ sh ed_file.sh && cat base.txt    
60
this is line3.
65
this is line1.
this is line2.
this is line 3 new.
this is line4.

关于ed的操作和参数,可以查看linux帮助或去搜索相关的资料。

3. shell控制数据库

假设执行下面的操作访问数据库。

$ mysql -u root
Welcome to the MySQL monitor.    Commands end with ; or \g.
Your MySQL connection id is 1257
Server version: 5.1.35-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

mysql> select * from user;
mysql> exit
Bye

如果我们要用shell脚本访问,则可以编写如下的脚本。

#!/bin/sh

mysql -u root << EOF
use mysql
select * from user;
exit
EOF

执行如下。

sh mysql_access.sh

可以看到结果相同。

使用嵌入文档Here Documents的更多相关文章

  1. mongodb 通过嵌入文档中的字段排序

    mongodb中的全部数据: db.testInfo.find({}) .sort({_id:-1}) .limit(100) 查询结果: /* 1 createdAt:2019/10/11 下午5: ...

  2. MongoDB(12)- 查询嵌入文档的数组

    插入测试数据 db.inventory.insertMany( [ { item: "journal", instock: [ { warehouse: "A" ...

  3. MongoDB .Net Driver(C#驱动) - 内嵌数组/嵌入文档的操作(增加、删除、修改、查询(Linq 分页))

    目录 一.前言 1. 运行环境 二.前期准备工作 1. 创建 MongoDBContext MongoDb操作上下文类 2.创建测试类 3.创建测试代码 三.内嵌数组增加元素操作 1.Update.S ...

  4. Mongodb中 Documents文档说明

    mongodb使用BSON格式存储数据记录. 如下图: 文档结构 文档有键值对组成, 有以下结构: {    field1: value1,    field2: value2,    ...     ...

  5. 01将图片嵌入到Markdown文档中

    将图片内嵌入Markdown文档中 将图片嵌入Markdown文档中一直是一个比较麻烦的事情.通常的做法是将图片存入本地某个路径或者网络存储空间,使用URL链接的形式插入图片: ![image][ur ...

  6. 2.QT中操作word文档

     Qt/Windows桌面版提供了ActiveQt框架,用以为Qt和ActiveX提供完美结合.ActiveQt由两个模块组成: A   QAxContainer模块允许我们使用COM对象并且可以 ...

  7. PHP 高级编程(1/5) - 编码规范及文档编写

    PHP 高级程序设计学习笔记20140612 软件开发中的一个重要环节就是文档编写.他可以帮助未来的程序维护人员和使用者理解你在开发时的思路.也便于日后重新查看代码时不至于无从下手.文档还有一个重要的 ...

  8. 手机打开PDF文档中文英文支持(乱码问题)解决攻略

    电子书的优点很多,随时随地阅读,无论白天黑夜走路坐车都能阅读:想确认一下某句话是不是这本书里的,搜索一下就可以知道:搬家也不用发愁,几万本书带在身上,依然轻松步行.我买了一台平板主要动因就是为了看书, ...

  9. ElasticSearch入门系列(三)文档,索引,搜索和聚合

    一.文档 在实际使用中的对象往往拥有复杂的数据结构 Elasticsearch是面向文档的,这意味着他可以存储整个对象或文档,然而他不仅仅是存储,还会索引每个文档的内容使之可以被搜索,在Elastic ...

随机推荐

  1. java Socket Tcp示例三则(服务端处理数据、上传文件)

    示例一: package cn.itcast.net.p5.tcptest; import java.io.BufferedReader;import java.io.IOException;impo ...

  2. 怎么将手动设定的IP变成固定的自动IP.

    怎么将手动设定的IP变成固定的自动IP. 基本原理是 是用的MAC 地址来绑定你的IP地址 方法1左下角 开始→运行→输入  cmd  回车→输入 ipconfig /all 用来查看你的MXC地址 ...

  3. Intellij IDEA 快捷键整理(dyCopy)

    原文:http://www.cnblogs.com/tonycody/p/3257601.html   [常规] Ctrl+Shift + Enter,语句完成 “!”,否定完成,输入表达式时按 “! ...

  4. 转:eclipse里面显示中文乱码

    显示中文会变成乱码解决方案:Windows- >Pereferences- >General->Workspace- >Text   File   Encoding   选项下 ...

  5. PHP关于进程池的优化

    本文打算从另一个角度来讨论问题,教大家如何配置高效的环境,如此同样能够达到优化的目的. pool 一个让人沮丧的消息是绝大多数 PHP 程序员都忽视了池的价值.这里所说的池可不是指数据库连接池之类的东 ...

  6. iOS archive(归档)

    归档是一种很常用的文件储存方法,几乎任何类型的对象都能够被归档储存(实际上是一种文件保存的形式),浏览网上的一些资料后,并结合自己的一些经验,总结成此文. 一.使用archiveRootObject进 ...

  7. ubuntu(14.04) remote access(远程连接数据库)

    1.修改mysql的配置文件.   /etc/mysql/my.cnf 把 bind-address 的那行代码注释掉,保存退出,重启mysql

  8. 数据源与JNDI资源实现JSP数据库连接池实例

    名词解释:JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通 ...

  9. PLSQL_统计信息系列01_统计信息的概念和重要性

    2014-12-18 Created By BaoXinjian

  10. Note for video Machine Learning and Data Mining——training vs Testing

    Here is the note for lecture five. There will be several points  1. Training and Testing  Both of th ...