mapfile [-n 计数] [-O 起始序号] [-s 计数] [-t] [-u fd] [-C 回调] [-c 量子] [数组]

两个作用:

一是给index数组读取标准输入来赋值;二是文件描述符来赋值。

mapfile 和readarray 互为同义词,用法完全相同。

bash提供了两个内置命令:readarray和mapfile,它们是同义词。它们的作用是从标准输入读取一行行的数据,然后每一行都赋值给一个数组的各元素。显然,在shell编程中更常用的是从文件、从管道读取,不过也可以从文件描述符中读取数据。

需要先说明的是,shell并不像其它专门的编程语言对数组、列表提供了大量的操作工具,反而直接操作文本文件更为常见(sed、awk等),所以mapfile用的并不多。

1.语法
mapfile [OPTIONS] ARRAY
readarray [OPTIONS] ARRAY

其中options:
-O INDEX  :指定从哪个索引号开始存储数据,默认存储数据的起始索引号为0
-n count  :最多只拷贝多少行到数组中,如果count=0,则拷贝所有行
-s count  :忽略前count行不读取
-c NUM    :每读取NUM行就调用一次"-C callback"选项指定的callback程序
-C callback:每读取"-c NUM"选项指定的NUM行就执行一次callback回调程序
-d string  :指定读取数据时的行分隔符,默认是换行符
-t        :移除尾随行分隔符,默认是换行符
-u fd      :指定从文件描述符fd而非标准输入中读取数据
•如果不指定ARRAY参数,则默认使用数组MAPFILE

•如果不指定"-O"选项,则在存储数据之前先清空数组(如果该数组已存在)

•给定了"-C callback"却没有给定"-c NUM"时,则默认为每5000行调用一次回调程序

•回调程序是在读取给定行数之后,赋值到数组元素之前执行的。所以流程为:"读NUM行-->callback-->赋值"

•每次调用回调函数时,都将调用callback之前的最后一行数据及其对应的索引号作为回调程序的参数。例如-c 3 -C callback,则会将索引号2和第3行内容,索引号5和第6行内容作为callback程序的参数

•"-t"去除行尾分隔符,一般来说都是换行符。用其他语言编程过的人都知道行尾换行符有多烦心,但对于shell编程来说,倒是无所谓

2.几个示例和注意事项

先创建一个示例用的文件alpha.log,每行一个小写字母,共26行:
$ echo {a..z} | tr " " "\n" >alpha.log
$ cat alpha.log
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z

读取该文件并将每一行存储到数组myarr中(如果不指定,则存储到默认的MAPFILE数组中)。
$ mapfile myarr <alpha.log
$ echo ${myarr[@]}
a b c d e f g h i j k l m n o p q r s t u v w x y z
$ echo ${myarr[2]}
c

既然是读取标准输入,常见的就有以下几种读取形式:
$ mapfile myarr <alpha.log            # 1.输入重定向
$ mapfile myarr < <(cat alpha.log)    # 2.进程替换
$ cat alpha.log | mapfile myarr      # 3.管道传递

第1、2种写法没什么问题,但第3种写法是有问题的。
$ cat alpha.log | mapfile myarr1
$ echo ${#myarr1[@]}
0

从结果中可以看到,myarr1根本就不存在。为什么?我在shell中while循环的陷阱中给出过解释。这里简单说明一下,对于管道组合的多个命令,它们都会放进同一个进程组中,会进入子shell执行相关操作。当执行完毕后,进程组结束,子shell退出。而子shell中设置的环境是不会粘滞到父shell中的(即不会影响父shell),所以myarr1数组是子shell中的数组,回到父shell就消失了。

解决方法是在子shell中操作数组:
$ cat alpha.log | { mapfile myarr1;echo ${myarr1[@]}; }

mapfile可以指定每读取多少行就执行一次的回调函数,并且会将执行回调函数时读取的最后一行和对应的索引号传递给回调函数作为它额外的参数。

一个简单的示例,每读取3行就执行一次echo,注意看下面传递给给echo的参数值。
$ mapfile -c 3 -C "echo" myarr <alpha.log
2 c

5 f

8 i

11 l

14 o

17 r

20 u

23 x

这里的echo就是回调函数。输出结果中每执行一次就有一空行,这是因为文件中数据是分行的,而echo又自带换行功能。所以,可以使用"-t"选项,在每次读取一行后就去掉该行的换行符。
$ mapfile -t -c 3 -C "echo" myarr <alpha.log
2 c
5 f
8 i
11 l
14 o
17 r
20 u
23 x

可以写一个脚本,或者定义一个函数作为回调程序,实现更复杂的功能,但一定要注意,mapfile传递给callback的两个参数总是最后两个参数。例如:
$ myecho(){ echo $@; };mapfile -t -c 3 -C "myecho haha" myarr <alpha.log
haha 2 c
haha 5 f
haha 8 i
haha 11 l
haha 14 o
haha 17 r
haha 20 u
haha 23 x

还可以将多个操作组合起来作为一个回调程序:
$ mapfile -t -c 3 -C "echo haha;echo" myarr<alpha.log
haha
2 c
haha
5 f
haha
8 i
haha
11 l
haha
14 o
haha
17 r
haha
20 u
haha
23 x

help mapfile

 mapfile: mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
Read lines from the standard input into an indexed array variable. Read lines from the standard input into the indexed array variable ARRAY, or
     from file descriptor FD if the -u option is supplied.  The variable MAPFILE
is the default ARRAY. Options:
-n count Copy at most COUNT lines. If COUNT is , all lines are copied.
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is .
-s count Discard the first COUNT lines read.
-t Remove a trailing newline from each line read.
-u fd Read lines from file descriptor FD instead of the standard input.
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
-c quantum Specify the number of lines read between each call to CALLBACK. Arguments:
ARRAY Array variable name to use for file data. If -C is supplied without -c, the default quantum is . When
CALLBACK is evaluated, it is supplied the index of the next array
element to be assigned and the line to be assigned to that element
as additional arguments. If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it. Exit Status:
Returns success unless an invalid option is given or ARRAY is readonly or
not an indexed array.

Linux命令:mapfile的更多相关文章

  1. Linux命令随笔

    Linux命令总结 man ==命令帮助; help ==命令的帮助(bash的内置命令); ls ==list,查看目录列表; -ld:查看目录权限; -l:(long)长格式显示属性; -F:给不 ...

  2. 1、Linux命令随笔

    1 Linux命令总结 2 3 man ==命令帮助; 4 help ==命令的帮助(bash的内置命令); 5 ls ==list,查看目录列表; 6 -ld:查看目录权限; 7 -l:(long) ...

  3. 第1章 Linux命令行简介

    1.1 Linux命令行概述 1.2 在Linux命令行下查看命令帮助 1.3 Linux关机.重启.注销命令 1.4 老男孩的运维思想 1.1 Linux命令行概述 1.1.1 Linux命令行的作 ...

  4. 六个优雅的 Linux 命令行技巧

    一些非常有用的命令能让命令行的生活更满足,使用 Linux 命令工作可以获得许多乐趣,但是如果您使用一些命令,它们可以减少您的工作或以有趣的方式显示信息时,您将获得更多的乐趣.在今天的文章中,我们将介 ...

  5. Linux实战教学笔记04:Linux命令基础

    第四节:Linux命令基础 标签(空格分隔):Linux实战教学笔记 第1章 认识操作环境 root:当前登陆的用户名 @分隔符 chensiqi:主机名 -:当前路径位置 用户的提示符 1.1 Li ...

  6. 像黑客一样使用 Linux 命令行

    前言 之前在博客园看到一篇介绍 IntelliJ IDEA 配置的文章,它里面用的是 gif 动态图片进行展示,我觉得很不错.所以在我今天以及以后的博文中,我也会尽量使用 gif 动图进行展示.制作 ...

  7. 11 个很少人知道但很有用的 Linux 命令

    Linux命令行吸引了大多数Linux爱好者.一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务.Linux命令和它们的转换对于Linux用户.Shell脚本程序员和管理员来说是最有 ...

  8. linux命令在线手册

    下面几个网址有一些 Linux命令的在线手册,而且还是中文的,还可以搜索.非常方便 Linux命令手册 Linux命令大全 Linux中文man在线手册 每日一linux命令

  9. 常用的一些linux命令

    最近接触到一些linux环境部署的事情,下面分享一些最近使用的比较频繁的一些linux命令~ 1.一次性移动多个文件到一个文件夹里 mv  被移动文件名 -t 目标文件夹 如:mv a.txt b.t ...

随机推荐

  1. ubuntu 网络配置

    检查网络配置命令:ifconfig 一.通过配置文件配置 新手没怎么用过Ubuntu,所以走了不少弯路,网上找了很多方法,大都没对我起到帮助作用,所以把自己的配置方法写一写. Ubuntu上连了两块网 ...

  2. 【转载】 pytorch笔记:06)requires_grad和volatile

    原文地址: https://blog.csdn.net/jiangpeng59/article/details/80667335 作者:PJ-Javis 来源:CSDN --------------- ...

  3. flask自定义处理错误方法

    自定义错误处理方法: 当客户端访问浏览器是,得到相对应的状态码,服务器通过状态码给用户相对应的页面. @app.errorhandler(404) def handle_404_error(err): ...

  4. Codeforces1062B. Math(合数分解)

    题目链接:传送门 题目: B. Math time limit per test second memory limit per test megabytes input standard input ...

  5. linux下安装mysql解决乱码、时间差、表的大小写问题

    编辑vi /etc/mysql/my.cnf,有的则是:/etc/my.cnf,加入 [client]default-character-set=utf8mb4 [mysql]default-char ...

  6. 安卓控制LED驱动编写

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 打开Android Stud ...

  7. Day 07 字符编码,文件操作

    今日内容 1.字符编码:人识别的语言与机器识别的语言转换的媒介 2.字符与字节:字符占多少字节,字符串转换 3.文件操作:操作硬盘的一块区域 字符编码 重点:什么是字符编码 人类能识别的字符等高级标识 ...

  8. 十五、springcloud(一)注册中心Eureka

    1.Eureka的基本架构 a.Eureka Server 提供服务注册和发现 b.Service Provider 服务提供方 将自身服务注册到Eureka,从而使服务消费方能够找到 c.Servi ...

  9. [转]linux下编译boost.python

    转自:http://blog.csdn.net/gong_xucheng/article/details/25045407 linux下编译boost.python 最近项目使用c++操作python ...

  10. 【python】脚本连续发送QQ邮件

    今天习得用python写一个连续发送QQ邮件的脚本,经过测试,成功给国内外的服务器发送邮件,包括QQ邮箱.163邮箱.google邮箱,香港科技大学的邮箱和爱丁堡大学的邮箱.一下逐步解答相关技巧. 首 ...