Bash实用技巧:同时循环两个列表
摘要:
你会学到一种原创的同时循环两个列表的方法。类似于Python或者Haskell的zip函数,非常简洁直观,效果如下:
- $ paste <(seq ) <(seq ) | while read host ip; do echo "vm$host: 172.16.116.$ip"; done
- vm1: 172.16.116.129
- vm2: 172.16.116.130
- vm3: 172.16.116.131
- vm4: 172.16.116.132
- vm5: 172.16.116.133
详情:
在实际应用中,经常需要我们输入对应的两个列表,比如主机名和IP:
- vm110 172.18.11.129
- vm111 172.18.11.130
- ...
如果有很多的话,使用awk处理一个临时文件,然后使用while read来循环是不错的(例如从Excel里面拷贝成文本文件,然后用awk提取相应的列到一个文件):
- awk '{print $1 $3}' orig.txt | while read host ip; do echo $host : $ip; done < temp.txt
但是,有没有能直接在命令行上生成这些列表并循环的方法呢?因为我更喜欢用for i in vm{110..120}; do echo $i; done这种方式来循环列表,但是这种方式只支持一个列表,怎么找到对应的另一个列表呢?
直接google,就会发现没有什么好的方法(以下均来自StackOverflow):
1、有的直接使用bash的数组甚至hash表,都是较新的版本才有,然后使用数字index来循环。这种方法一点也不直观:
- list1="a b c"
- list2="1 2 3"
- array1=($list1)
- array2=($list2)
- count=${#array1[@]}
- for i in `seq $count`
- do
- echo ${array1[$i-]} ${array2[$i-]}
- done
谁也不想写类似${#array1[@]}这样的复杂表达,因为我们不是在编程,而是在输入一条命令。
2、有的使用了各种正则表达式命令,我一眼看不出来什么意思,没人会为了循环两个列表,去专门写一个脚本文件:
- #!/bin/sh
- list1="1 2 3"
- list2="a b c"
- while [ -n "$list1" ]
- do
- head1=`echo "$list1" | cut -d ' ' -f `
- list1=`echo "$list1" | sed 's/[^ ]* *\(.*\)$/\1/'`
- head2=`echo "$list2" | cut -d ' ' -f `
- list2=`echo "$list2" | sed 's/[^ ]* *\(.*\)$/\1/'`
- echo $head1 $head2
- done
还有其他几种,有兴趣的可以去看看,http://stackoverflow.com/questions/546817/iterating-over-two-lists-in-parallel-in-bin-sh。
但是有一种方法提醒了我:
- list1="aaa1 aaa2 aaa3"
- list2="bbb1 bbb2 bbb3"
- tmpfile1=$( mktemp /tmp/list.XXXXXXXXXX ) || exit
- tmpfile2=$( mktemp /tmp/list.XXXXXXXXXX ) || exit
- echo $list1 | tr ' ' '\n' > $tmpfile1
- echo $list2 | tr ' ' '\n' > $tmpfile2
- paste $tmpfile1 $tmpfile2
- rm --force $tmpfile1 $tmpfile2
这种方法创建了两个临时文件,好像还不如前面的方法,但是在我看来,这很有启发性:他使用了paste来结合两个列表,这是linux下原生的合并列表命令,相当于其他语言的zip。
另外,临时文件也可以避免,因此我想出了以下的方法(并不推荐):
- paste <(echo vm{..} | tr ' ' '\n') <(echo 172.16..{..} | tr ' ' '\n') | while read host ip; do echo $host: $ip; done
其中vm{1..5}会产生“vm1 vm2 vm3 vm4 vm5”,以空格分隔,而paste是把两个列文件合并成一个,所以必须把空格替换成换行,这就是tr做的事。明显使用tr很不好,增加了命令的复杂度。
另外<()是执行一个命令,并把这个命令输出当作一个文件的意思。
于是我想到了seq,好像可以指定分隔符,一查文档,居然默认就是换行,于是命令得以大幅简化:
- paste <(seq ) <(seq ) | while read host ip; do echo "vm$host: 172.16.116.$ip"; done
这个命令可以循环2个及以上同等长度的列表,而且非常直观。就是开头提到的方法。
Bash实用技巧:同时循环两个列表的更多相关文章
- bash 实用技巧
一..将文件的内容赋给一个变量: file=$(cat filelist) file=$(< file) NOTE:后者性能比前者好 二..bash 分组匹配: HOSTNAME='mysql- ...
- python 如何在一个for循环中遍历两个列表
是我在看<笨方法学python>过程中发现有一行代码看不懂--" for sentence in snippet, phrase:",所以研究了半天,感觉挺有收获的.所 ...
- python中如何在一个for循环中遍历两个列表
`其实就是用zip把两个列表包装起来: for x, y in zip(list1, list2)
- 转:Eclipse快捷键和实用技巧
原文地址:Eclipse快捷键和实用技巧 工欲善其事,必先利其器.对于程序员来说,Eclipse便是其中的一个“器”.本文会从Eclipse快捷键和实用技巧这两个篇章展开介绍.Eclipse快捷键用熟 ...
- JavaScript 实用技巧和写法建议
1.前言 从大学到现在,接触前端已经有几年了,感想方面,就是对于程序员而言,想要提高自己的技术水平和编写易于阅读和维护的代码,我觉得不能每天都是平庸的写代码,更要去推敲,去摸索和优化代码,总结当中的技 ...
- Notepad++ 实用技巧
Notepad++是一款开源的文本编辑器,功能强大.很适合用于编辑.注释代码.它支持绝大部分主流的编程语言. 本文主要列举了本人在实际使用中遇到的一些技巧. 快捷键 自定义快捷键 首先,需要知道的是: ...
- Vim 实用技术,第 1 部分: 实用技巧(转)
原文链接:http://blog.jobbole.com/20604/ 0. Vim 简介 作为开源世界最重要的编辑器之一(另一个是 Emacs),Vim 以其强大的功能和可定制能力被众多开发者所喜爱 ...
- c++实用技巧
原地址:http://www.cnblogs.com/easymind223/articles/2576904.html 晚上的时间总是习惯性的在cnblogs逛街,今天又看到了好文章,其c++味道浓 ...
- js基础进阶--编的实用技巧(一)
我的个人博客:http://www.xiaolongwu.cn 在平时的开发中,编码技巧很重要,会让你少写很多代码,起到事倍功半的效果. 下面总结几种简单的技巧,大家共同学习一下 1. 利用+.-./ ...
随机推荐
- makefile多目录的.c 格式.cpp混合编译
# # c.cpp混合编译的makefile模板 # # BIN = test.exe CC = gcc CPP = g++ #这里只加入库头文件路径及库路径 INCS = -I"c:/mi ...
- perl中的运算符
字符计算的运算符
- expecting SSH2_MSG_KEX_ECDH_REPLY ssh_dispatch_run_fatal问题解决
设置client的mtu ifconfig eth0 mtu 576 Ultimately, I added the following to /etc/ssh/ssh_config: Host * ...
- ajax无刷新上传图片
页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...
- [题解]某模拟题(USACO月赛部分题+noip2005部分题)
题目描述 农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上.FJ有一辆拖拉机,也在农场上.拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内.拖拉 ...
- mysql 字符串处理优化
周五下午,同事突然说有个存储过程要帮忙优化,就拿来看看,大概看了下: 数据库端需求:数据库中要存储一个AppID字段,对应一个Account可以自行设置自己的AppID(我就不从业务上多说了), 以前 ...
- 自动化测试工具QTP和SilkTest横向PK(转)
转自:http://www.uml.org.cn/Test/201405212.asp?artid=1686 众所周知,自动化测试工具曾几何时三足鼎立,Mercury QTP/WinRunner系.I ...
- php数组函数
1.键值函数 array_values()返回数组元素值,组成一个新的索引数组 2.array_keys()返回数组所有键名,组成一个索引数组 3.in_array()检查数组中是否存在某个值 4.a ...
- 正向代理与反向代理的区别【Nginx读书笔记】(zz)
正向代理与反向代理的区别[Nginx读书笔记] 正向代理的概念 正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 ...
- About-JavaOOAD
软件工程三要素 方法:完成软件开发的各项任务的技术方法,为软件开发提供 “如何做” 的技术 工具:为运用方法而提供的自动的或半自动的软件工程的支撑环境 过程:为了获得高质量的软件所需要完成的一 ...