Bash实用技巧:同时循环两个列表
摘要: 你会学到一种原创的同时循环两个列表的方法。类似于Python或者Haskell的zip函数,非常简洁直观,效果如下: $ paste ( seq 1 5 ) ( seq 129 133 ) | while read host ip; do echo " vm$host: 172.16.116.$ip " ; done vm1: 172.16 . 116.129 vm2: 172
摘要:
你会学到一种原创的同时循环两个列表的方法。类似于Python或者Haskell的zip函数,非常简洁直观,效果如下:
$ paste seq <span>1</span> <span>5</span>) seq <span>129</span> <span>133</span>) | <span>while</span> read host ip; <span>do</span> <span>echo</span> <span>"</span><span>vm$host: 172.16.116.$ip</span><span>"</span>; <span>done</span><span> vm1: </span><span>172.16</span>.<span>116.129</span><span> vm2: </span><span>172.16</span>.<span>116.130</span><span> vm3: </span><span>172.16</span>.<span>116.131</span><span> vm4: </span><span>172.16</span>.<span>116.132</span><span> vm5: </span><span>172.16</span>.<span>116.133</span>
详情:
在实际应用中,经常需要我们输入对应的两个列表,比如主机名和IP:
vm110 <span>172.18</span>.<span>11.129</span><span> vm111 </span><span>172.18</span>.<span>11.130</span><span> ...</span>
如果有很多的话,使用awk处理一个临时文件,然后使用while read来循环是不错的(例如从Excel里面拷贝成文本文件,然后用awk提取相应的列到一个文件):
<span>awk</span> <span>'</span><span>{print $1 $3}</span><span>'</span> orig.txt | <span>while</span> read host ip; <span>do</span> <span>echo</span> $host : $ip; <span>done</span> <p>但是,有没有能直接在命令行上生成这些列表并循环的方法呢?因为我更喜欢用for i in vm{110..120}; do echo $i; done这种方式来循环列表,但是这种方式只支持一个列表,怎么找到对应的另一个列表呢?</p> <p>直接google,就会发现没有什么好的方法(以下均来自StackOverflow):</p> <p>1、有的直接使用bash的数组甚至hash表,都是较新的版本才有,然后使用数字index来循环。这种方法一点也不直观:</p> <p> </p><pre class="brush:php;toolbar:false">list1=<span>"</span><span>a b c</span><span>"</span><span> list2</span>=<span>"</span><span>1 2 3</span><span>"</span><span> array1</span>=<span>($list1) array2</span>=<span>($list2) count</span>=<span>${#array1[@]} </span><span>for</span> i <span>in</span> `<span>seq</span> <span>1</span><span> $count` </span><span>do</span> <span>echo</span> ${array1[$i-<span>1</span>]} ${array2[$i-<span>1</span><span>]} </span><span>done</span>
谁也不想写类似${#array1[@]}这样的复杂表达,因为我们不是在编程,而是在输入一条命令。
2、有的使用了各种正则表达式命令,我一眼看不出来什么意思,没人会为了循环两个列表,去专门写一个脚本文件:
#!/bin/<span>sh</span><span> list1</span>=<span>"</span><span>1 2 3</span><span>"</span><span> list2</span>=<span>"</span><span>a b c</span><span>"</span> <span>while</span> [ -n <span>"</span><span>$list1</span><span>"</span><span> ] </span><span>do</span><span> head1</span>=`<span>echo</span> <span>"</span><span>$list1</span><span>"</span> | <span>cut</span> -d <span>'</span> <span>'</span> -f <span>1</span><span>` list1</span>=`<span>echo</span> <span>"</span><span>$list1</span><span>"</span> | <span>sed</span> <span>'</span><span>s/[^ ]* *\(.*\)$/\1/</span><span>'</span><span>` head2</span>=`<span>echo</span> <span>"</span><span>$list2</span><span>"</span> | <span>cut</span> -d <span>'</span> <span>'</span> -f <span>1</span><span>` list2</span>=`<span>echo</span> <span>"</span><span>$list2</span><span>"</span> | <span>sed</span> <span>'</span><span>s/[^ ]* *\(.*\)$/\1/</span><span>'</span><span>` </span><span>echo</span><span> $head1 $head2 </span><span>done</span>
还有其他几种,有兴趣的可以去看看,http://stackoverflow.com/questions/546817/iterating-over-two-lists-in-parallel-in-bin-sh。
但是有一种方法提醒了我:
list1=<span>"</span><span>aaa1 aaa2 aaa3</span><span>"</span><span> list2</span>=<span>"</span><span>bbb1 bbb2 bbb3</span><span>"</span><span> tmpfile1</span>=$( <span>mktemp</span> /tmp/list.XXXXXXXXXX ) || exit <span>1</span><span> tmpfile2</span>=$( <span>mktemp</span> /tmp/list.XXXXXXXXXX ) || exit <span>1</span> <span>echo</span> $list1 | <span>tr</span> <span>'</span> <span>'</span> <span>'</span><span>\n</span><span>'</span> ><span> $tmpfile1 </span><span>echo</span> $list2 | <span>tr</span> <span>'</span> <span>'</span> <span>'</span><span>\n</span><span>'</span> ><span> $tmpfile2 paste $tmpfile1 $tmpfile2 </span><span>rm</span> --force $tmpfile1 $tmpfile2
这种方法创建了两个临时文件,好像还不如前面的方法,但是在我看来,这很有启发性:他使用了paste来结合两个列表,这是linux下原生的合并列表命令,相当于其他语言的zip。
另外,临时文件也可以避免,因此我想出了以下的方法(并不推荐):
paste echo vm{<span>1</span>..<span>5</span>} | <span>tr</span> <span>'</span> <span>'</span> <span>'</span><span>\n</span><span>'</span>) echo <span>172.16</span>.<span>116</span>.{<span>129</span>..<span>133</span>} | <span>tr</span> <span>'</span> <span>'</span> <span>'</span><span>\n</span><span>'</span>) | <span>while</span> read host ip; <span>do</span> <span>echo</span> $host: $ip; <span>done</span>
其中vm{1..5}会产生“vm1 vm2 vm3 vm4 vm5”,以空格分隔,而paste是把两个列文件合并成一个,所以必须把空格替换成换行,这就是tr做的事。明显使用tr很不好,增加了命令的复杂度。
另外
于是我想到了seq,好像可以指定分隔符,一查文档,居然默认就是换行,于是命令得以大幅简化:
paste seq <span>1</span> <span>5</span>) seq <span>129</span> <span>133</span>) | <span>while</span> read host ip; <span>do</span> <span>echo</span> <span>"</span><span>vm$host: 172.16.116.$ip</span><span>"</span>; <span>done</span><span><br></span>
这个命令可以循环2个及以上同等长度的列表,而且非常直观。就是开头提到的方法。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Pythonは、必要に応じてさまざまな目的に使用できる非常に便利なソフトウェアです。 Python は、Web 開発、データ サイエンス、機械学習、その他自動化が必要な多くの分野で使用できます。これらのタスクの実行に役立つさまざまな機能が備わっています。 Python リストは、Python の非常に便利な機能の 1 つです。名前が示すように、リストには保存したいすべてのデータが含まれています。それは基本的に、さまざまな種類の情報のセットです。角括弧を削除するさまざまな方法 多くの場合、ユーザーはリスト項目が角括弧内に表示される状況に遭遇します。この記事では、リストを見やすくするためにこれらの括弧を削除する方法について詳しく説明します。文字列内の括弧や置換関数を削除する最も簡単な方法の 1 つは、次のとおりです。

Python の count() 関数を使用してリスト内の要素の数を計算する方法には、特定のコード サンプルが必要です。Python は強力で習得しやすいプログラミング言語として、さまざまなデータ構造を処理するための組み込み関数を多数提供しています。その 1 つは count() 関数で、リスト内の要素の数をカウントするために使用できます。この記事では、count()関数の使い方と具体的なコード例を詳しく説明します。 count() 関数は Python の組み込み関数であり、特定の値を計算するために使用されます。

Tomcat404 エラーを迅速に解決するための実用的なヒント Tomcat は、一般的に使用される JavaWeb アプリケーション サーバーであり、JavaWeb アプリケーションの開発およびデプロイ時によく使用されます。ただし、Tomcat から 404 エラーが発生する場合があります。これは、Tomcat が要求されたリソースを見つけられないことを意味します。このエラーは複数の要因によって発生する可能性がありますが、この記事では、Tomcat 404 エラーを迅速に解決するのに役立ついくつかの一般的な解決策とヒントについて説明します。 URLパスを確認する

iOS17のiPhoneでGroceryListを作成する方法 リマインダーアプリでGroceryListを作成するのは非常に簡単です。リストを追加して項目を入力するだけです。アプリは商品を自動的にカテゴリーに分類し、パートナーやフラットパートナーと協力してストアで購入する必要のあるもののリストを作成することもできます。これを行う完全な手順は次のとおりです: ステップ 1: iCloud リマインダーをオンにする 奇妙に聞こえるかもしれませんが、Apple は、iOS17 で GroceryList を作成するには iCloud からのリマインダーを有効にする必要があると言っています。その手順は次のとおりです: iPhone の設定アプリに移動し、[あなたの名前] をタップします。次に、「i」を選択します

Java で大きなファイルの読み取り例外を効率的に解決するための実践的なヒントには、特定のコード例が必要です 概要: 大きなファイルを処理する場合、Java はメモリ オーバーフローやパフォーマンスの低下などの問題に直面する可能性があります。この記事では、Java の大きなファイルの読み取り例外を効果的に解決するためのいくつかの実践的なテクニックを紹介し、具体的なコード例を示します。背景: 大きなファイルを処理する場合、検索、分析、抽出などの処理のためにファイルの内容をメモリに読み取る必要がある場合があります。ただし、ファイルが大きい場合、次の問題がよく発生します。 メモリ オーバーフロー: ファイル全体を一度にコピーしようとする

iOS 17 で、Apple は食料品の買い物に出かけるときに役立つ便利な小さなリスト機能をリマインダー アプリに追加しました。この記事を読んで使い方を学び、店舗に行く時間を短縮しましょう。新しい「食料品」リスト タイプ (米国外では「ショッピング」という名前) を使用してリストを作成すると、さまざまな食品や食料品を入力し、カテゴリー別に自動的に整理できます。この構成により、食料品店や買い物中に必要なものを簡単に見つけることができます。アラートで利用できるカテゴリ タイプには、農産物、パンとシリアル、冷凍食品、スナックとキャンディー、肉、乳製品、卵とチーズ、焼き菓子、焼き菓子、家庭用品、パーソナルケアとウェルネス、ワイン、ビールと蒸留酒が含まれます。以下はiOS17で作成したものです

違いについて説明する前に、まず Python リストの Del と Remove() が何であるかを理解しましょう。 Python リストの Del キーワード Python の del キーワードは、リストから 1 つ以上の要素を削除するために使用されます。すべての要素を削除する、つまりリスト全体を削除することもできます。 del キーワードを使用して Python リストから要素を削除する例 #CreateaListmyList=["Toyota","Benz","Audi","Bentley"]print("List="

Python は、そのシンプルさと多用途性により、さまざまなアプリケーションで最も人気のあるプログラミング言語の 1 つとなっています。経験豊富な開発者でも、コーディングを始めたばかりでも、Python は複雑なタスクを管理しやすくする幅広い機能とライブラリを提供します。この記事では、リストに基づいて複数のディレクトリを作成するプロセスを自動化することで Python が役立つ実際的なシナリオを検討します。 Python の組み込みモジュールとテクニックの力を活用することで、手動介入を必要とせずにこのタスクを効率的に処理できます。このチュートリアルでは、複数のディレクトリを作成する問題を詳しく説明し、Python を使用してこの問題を解決するさまざまな方法を提供します。この記事が終わるまでに、私たちの目標はあなたにあります
