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. CameraManager与CameraDevice与ICameraService的相应关系

    Camera2 AP Framewok中有三个比較重要的组件:CameraManager.CameraDevice.ICameraService,他们的相应关系例如以下: 一个Context中会有一个 ...

  2. ZOJ 2314 有上下界的网络流

    problemCode=2314">点击打开链接 题意:给定m条边和n个节点.每条边最少的流量和最多的流量.保证每一个节点的出入流量和相等,问能够形成吗,能够则输出每条边的流量 思路: ...

  3. How to forcefully delete a daemonset or a pod in kubernetes cluster

    I have setup a kubernetes cluster which is working fine. I created deployment with type as daemonset ...

  4. 使用DotNetBarcode制作基本常用条码

    核心代码: /// <summary> /// 打印一维码 /// </summary> /// <param name="codeText"> ...

  5. HDUOJ---1867 A + B for you again

    A + B for you again Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. 【LeetCode】136. Single Number (4 solutions)

    Single Number Given an array of integers, every element appears twice except for one. Find that sing ...

  7. c# 网站生成静态页面

    在一些需要经常更新页面数据的网站中,一般访问量不是很大的都直接发布的是带后台代码,每次访问都是有数据库交互的.但是一旦访问量增加了,那么这些服务器开销变成本就要考虑进来了,像一些文章,后台编辑后,文章 ...

  8. Windows命令-route

    Windows route命令 添加一条永久网关:route add 0.0.0.0 mask 0.0.0.0 192.168.2.1 -p例如: route -p add 192.168.0.0 m ...

  9. java程序员学习路线图 java程序员进阶路线

  10. NSURLRequestCachePolicy 缓存策略

    1> NSURLRequestUseProtocolCachePolicy = 0, 默认的缓存策略, 如果缓存不存在,直接从服务端获取.如果缓存存在,会根据response中的Cache-Co ...