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. 利用+.-./ ...
随机推荐
- UART UVM验证平台平台搭建总结
tb_top是整个UVM验证平台的最顶层:tb_top中例化dut,提供时钟和复位信号,定义接口以及设置driver和monitor的virual interface,在intial中调用run_te ...
- 使用CocoaPods配置工程
1.首先搭建环境,配置CocoaPods,具体请参考 http://code4app.com/article/cocoapods-install-usage 2.打开终端,输入 cd 空格 把工程拖入 ...
- C++中四种转换类型的区别
一.四种转换类型比较: 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可 ...
- 高版本Chrome不支持showModalDialog
高版本Chrome不支持window.showModalDialog,可用window.open代替 var url = "https://www.baidu.com"; var ...
- jQuery Mobile 过渡效果
jQuery Mobile 包含了允许您选择页面打开方式的 CSS 效果. jQuery Mobile 过渡效果 jQuery Mobile 拥有一系列关于如何从一页过渡到下一页的效果. 注释:如需实 ...
- Position a child div relative to parent container in CSS: [设置 子DIV位置 跟 父DIV相关联]
最近调DIV的位置比较头疼,各种position: relative / absolute google到一篇好文章[http://www.webdevdoor.com/html-css/css-po ...
- zabbix监控超详细搭建过程
监控及zabbix 目录: 1 监控分类... 1 1.1 硬件监控... 1 1.2 系统监控... 2 1.3 网络监控... 3 1.4 ...
- [linux]linux普通用户安装rpm软件
先下载rpm文件 yumdownloader xxxx.rpm 直接wget等其他方式下载也可以. 解压 rpm2cpio xxxx.rpm |cpio -idvm 修改环境变量 将新增的软件的可执行 ...
- 20145225 《Java程序设计》第2周学习总结
20145225<Java程序设计> 第2周学习总结 教材学习内容总结 3.1.1Java的类型 分为基本类型(Primitive type)和类类型(Class type) 基本类型: ...
- Web开发中的主要概念
一.Web开发中的主要概念1.静态资源:一成不变的.html.js.css2.动态资源:JavaWeb.输出或产生静态资源.(用户用浏览器看到的页面永远都是静态资源) 3.JavaEE:十三种技术的集 ...