摘要:

你会学到一种原创的同时循环两个列表的方法。类似于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实用技巧:同时循环两个列表的更多相关文章

  1. bash 实用技巧

    一..将文件的内容赋给一个变量: file=$(cat filelist) file=$(< file) NOTE:后者性能比前者好 二..bash 分组匹配: HOSTNAME='mysql- ...

  2. python 如何在一个for循环中遍历两个列表

    是我在看<笨方法学python>过程中发现有一行代码看不懂--" for sentence in snippet, phrase:",所以研究了半天,感觉挺有收获的.所 ...

  3. python中如何在一个for循环中遍历两个列表

    `其实就是用zip把两个列表包装起来:  for x, y in zip(list1, list2) 

  4. 转:Eclipse快捷键和实用技巧

    原文地址:Eclipse快捷键和实用技巧 工欲善其事,必先利其器.对于程序员来说,Eclipse便是其中的一个“器”.本文会从Eclipse快捷键和实用技巧这两个篇章展开介绍.Eclipse快捷键用熟 ...

  5. JavaScript 实用技巧和写法建议

    1.前言 从大学到现在,接触前端已经有几年了,感想方面,就是对于程序员而言,想要提高自己的技术水平和编写易于阅读和维护的代码,我觉得不能每天都是平庸的写代码,更要去推敲,去摸索和优化代码,总结当中的技 ...

  6. Notepad++ 实用技巧

    Notepad++是一款开源的文本编辑器,功能强大.很适合用于编辑.注释代码.它支持绝大部分主流的编程语言. 本文主要列举了本人在实际使用中遇到的一些技巧. 快捷键 自定义快捷键 首先,需要知道的是: ...

  7. Vim 实用技术,第 1 部分: 实用技巧(转)

    原文链接:http://blog.jobbole.com/20604/ 0. Vim 简介 作为开源世界最重要的编辑器之一(另一个是 Emacs),Vim 以其强大的功能和可定制能力被众多开发者所喜爱 ...

  8. c++实用技巧

    原地址:http://www.cnblogs.com/easymind223/articles/2576904.html 晚上的时间总是习惯性的在cnblogs逛街,今天又看到了好文章,其c++味道浓 ...

  9. js基础进阶--编的实用技巧(一)

    我的个人博客:http://www.xiaolongwu.cn 在平时的开发中,编码技巧很重要,会让你少写很多代码,起到事倍功半的效果. 下面总结几种简单的技巧,大家共同学习一下 1. 利用+.-./ ...

随机推荐

  1. How to Shorten the Paper

    . Remember: you are writing for an expert. Cross out all that is trivial or routine. . Avoid repetit ...

  2. MongoDB中的连接池

    参见 http://www.cnblogs.com/huangfox/archive/2012/04/01/2428947.html

  3. Android常见崩溃或闪退的问题描述及原因总结、及与性能相关的模块——持续更新

    1.nullpointer——就是使用一个对象的时候还没有对其进行初始化导致该问题 一般在何种情况下容易出现呢? (1)父窗口+子窗口同时出现的,父窗口因为某种原因消掉了,子窗口还在,操作子窗口找不到 ...

  4. Ubuntu 14.04 (32位)上搭建Hadoop 2.5.1单机和伪分布式环境

    引言 一直用的Ubuntu 32位系统(准备下次用Fedora,Ubuntu越来越不适合学习了),今天准备学习一下Hadoop,结果下载Apache官网上发布的最新的封装好的2.5.1版,配置完了根本 ...

  5. zlib快速编译脚本

    zlib允许使用IDE编译生成dll以及静态库,高版本写一个脚本就能轻松的一键编译生成静态/动态lib以及dll文件 以下是一句话编译批处理脚本 nmake -f win32\Makefile.msc ...

  6. Python:集合

    set集合: 特点:无序,元素不重复 功能:关系测试,去重 集合创建: >>> s = set('python') >>> s {'p', 't', 'y', 'h ...

  7. 使用并行的方法计算斐波那契数列 (Fibonacci)

    更新:我的同事Terry告诉我有一种矩阵运算的方式计算斐波那契数列,更适于并行.他还提供了利用TBB的parallel_reduce模板计算斐波那契数列的代码(在TBB示例代码的基础上修改得来,比原始 ...

  8. Linux下apache日志分析与状态查看方法

    假设apache日志格式为:118.78.199.98 – - [09/Jan/2010:00:59:59 +0800] “GET /Public/Css/index.css HTTP/1.1″ 30 ...

  9. [linux] 线程和wait命令,sleep命令

    在linux脚本编程中使用多线程编程,其中wait命令可以实现shell的多线程同步控制. 1. 启动后台子任务 在执行命令后加&操作符,表示将命令放在子shell中异步执行.可以达到多线程效 ...

  10. NFS配置

    一,配置nfs服务端 nfs服务端IP:192.168.1.10 1,安装nfs [root@localhost ~]# yum install -y nfs-utils Loaded plugins ...