15.2.1 命令行基础

本节会简单介绍一下在使用GMT的过程中需要掌握的一些与GMT无关的基础知识。如无特殊提示,则表明该基础知识既适用于Linux、macOS也适用于Windows。

文件后缀

经常接触的 .doc.ppt,以及前面提到的 .sh.bat 等,都是文件后缀。文件后缀的主要作用是表明该文件是什么格式或什么类型的文件。

Windows下,每一个文件后缀都与特定的应用程序相关联,比如后缀为 .doc 的文件默认都是用MS Word打开,当然也可以选择用其他应用程序打开。后缀为 .bat 的文件,在双击的时候会直接被执行,想要编辑的话就需要右键编辑。

Linux/macOS下,文件后缀就没那么重要了。一个bash脚本可以用 .sh 结尾,也可以用 .gmt 结尾,甚至没有后缀。不管后缀是什么,如果用 sh 来执行该脚本,这个脚本就会被当成bash脚本;如果用 perl 来执行该脚本,这个脚本就会被当成Perl脚本(bash脚本被当成Perl脚本来解释,会直接报错)。因而在Linux/macOS下,对文件的后缀并没有严格的要求,后缀的作用仅仅是让用户一眼就可以看出来文件是什么格式而已。

标准输出流和标准错误流

标准输出流(STDOUT)用于显示输出数据,标准错误流(STDERR)用于显示错误消息。一般来说,标准输出流和标准错误流都是屏幕。

GMT中,模块的正常输出都发送到标准输出流,模块的语法、警告、错误以及进程报告都发送到标准错误流,由于这两者默认情况下都是屏幕,所以标准输出流和标准错误流会混在一起,因而需要对输出进行重定向。常见的做法可以是下面的一种或多种的组合:

  1. 将标准输出流重定向到数据文件中
  2. 将标准错误流重定向到日志文件中
  3. 将标准输出流通过管道传递给下一个命令

重定向

这里只介绍GMT中经常使用的最简单的重定向功能。

对于标准输出流:

  • >:将标准输出流重定向到新文件中。若该文件已存在,则覆盖文件中原内容;若该文件不存在,则创建该文件
  • >>:将标准输出流追加到文件中。若文件已存在,则将标准输出流追加到已有文件后面;若文件不存在,则创建该文件

对于标准错误流,重定向符号是 2>2>>。这里的 2 表示标准错误流,大于号的含义与标准输出流相同。

管道

除了上面提到的重定向符号之外,还有一种常用的类似重定向的操作,即管道,用符号 | 表示。

管道的作用是,将上一个命令的标准输出作为下一个命令的标准输入。

举例如下,假设文件 input.dat 中包含了一系列地震的经度、纬度和震级共三列数据,想要在图上画很多圆表示地震的位置,圆的大小表示震级的大小。可以用类似如下命令:

gmt psxy input.dat -Rxxx ... > test.ps

此时 plot 模块会读取 input.dat 文件的内容作为其输入。

也可以使用管道:

cat input.dat | gmt psxy ...

cat 命令会读取 input.dat 的内容并将其发送到标准输出流,由于使用了管道,标准输出流中的内容被 gmt plot 接收作为自己的标准输入流。

当然还可以使用 gawk

gawk '{print $1, $2, $3/10}' input.dat | gmt psxy ...

gawk 会读取 input.dat 的内容,并对数据做简单处理并输出。

标准输入流

GMT的某些模块需要数据才可以画图,这些数据可以来自于文件,或来自于标准输入流。

比如要绘制地震的分布,可以把地震的经纬度信息放在文件 event.loc 中,其内容如下:

100.0 40.0
110.0 45.0

将这些数据传给GMT有如下几种方法。

  1. 直接在命令行指定文件名,命令会自动读取该文件的内容:

    gmt psxy event.loc -R70/140/20/60 -JM6i -B5 -Sc0.2c -Gred > map.ps
    
  2. 直接从键盘输入

    标准输入流的默认设备是键盘。下面的例子中直接从键盘输入GMT所需的数据。首先执行 gmt plot 命令,然后键盘键入两行数据,再按下 Ctrl+C 中断输入,GMT会给出中断警告,然后按下回车键即可:

    $ gmt psxy -R70/140/20/60 -JM6i -B5 -Sc0.2c -Gred > map.ps
    100.0 40.0
    110.0 45.0
    Interrupt at /lib64/libc.so.6(__read+0x10)[0x7f8383e8d980]
    Tuser: 0.004s Tsys: 0.004s VmRSS: 8340kB VmSize: 114268kB
    Press return to continue, ctrl-c to quit.
    $
    
  3. 标准输入流重定向 <

    < 的作用是读取 < 后的文件的内容并将其作为标准输入流,与直接在命令行指定文件名类似:

    gmt psxy -R70/140/20/60 -JM6i -B5 -Sc0.2c -Gred > map.ps < event.loc
    
  4. 通过管道输入

    管道可以将前一个命令的标准输出作为后一个命令的标准输入:

    cat event.loc | gmt psxy -R70/140/20/60 -JM6i -B5 -Sc0.2c -Gred > map.ps
    
  5. Here Documents

    示例如下,两个 EOF 之间的所有数据都会被传递给GMT:

    gmt psxy -R70/140/20/60 -JM6i -B5 -Sc0.2c -Gred > map.ps << EOF
    100.0 40.0
    110.0 45.0
    EOF
    

说明:

  1. 上面列出的5种方式中,常用的是第1、4、5种;
  2. Here Documents方法中,EOF 可以被替换成其他任意字符(比如 END ),只要保证开始和结束的符号一致即可
  3. Here Documents方法仅适用于bash,不适用于bat

倒引号

倒引号,也称为反引号,英文为backtick或backquote。键盘上按键 1 左边的键,那个像顿号的就是。倒引号的作用是将一个命令的标准输出插在另一个命令的任意位置。

例如,想要用 plot 绘制某数据时,需要提供数据的范围 -R,而 gmtinfo 模块可以用于计算并输出数据的范围,即需要将 gmtinfo 的输出作为 plot 的一个选项。

比如:

$ gmt info in.dat -I1/1
-R0/10/0/10
$ gmt psxy in.dat -JX10c -R0/10/0/10 > map.ps

上面的做法需要人工干预,不适合脚本自动化,可以利用倒引号将 gmtinfo 的输出保存到变量中:

#!/bin/bash

R=`gmt info input -I1/1`
gmt psxy in.dat -JX10c $R > map.ps

上面的例子还可以进一步简化。此处变量 $R 只需要用一次,因而没有必要把 gmtinfo 的输出信息保存到变量中,可以直接在 psxy 命令中使用倒引号:

$ gmt psxy in.dat -JX10c `gmt info in.dat -I1/1` > map.ps

此处,bash首先会执行倒引号内的命令,然后用 gmtinfo 的输出替换整个倒引号部分,再执行替换后的命令。这样的写法更易于自动化。

通配符

UNIX下提供了通配符功能,使得可以基于文件名的模式选择一组文件。

UNIX下的通配符包括:

表 15.1 通配符
通配符 含义
* 匹配任意数目的任意字符
? 匹配任意单个字符
[ABC] 匹配中括号内的任意单个字符
[A-Z] 匹配给定范围内的任意单个字符

示例:

  1. data_*.d 会匹配所有以 data_ 开头,并以 .d 结尾的文件
  2. line_?.d 会匹配所有以 line_ 开头,后接任意一个字符,并以 .d 结尾的文件
  3. section_1[0-9]0.part 会匹配 section_1x0.partx 为0到9的文件
  4. section_[12].part 会匹配 section_1.partsection_2.par 两个文件