GNU/Linux >> Linux の 問題 >  >> Linux

Linux Bashプログラミングの概要:5つの`for`ループのヒント

すべてのシステム管理者は、おそらく何年にもわたって学んだスキルを持っており、「それが私の世界を変えた」と指摘して言うことができます。そのスキル、またはそのビットの情報、またはそのテクニックは、私が物事を行う方法を変えました。私たちの多くにとって、それはループです。 バッシュで。確かにより堅牢またはスケーラブルな自動化へのアプローチは他にもあります。それらのほとんどは、forのシンプルさとすぐに使える使いやすさに匹敵しません。 ただし、ループします。

何千ものシステムの構成を自動化したい場合は、おそらくAnsibleを使用する必要があります。ただし、1,000個のファイルの名前を変更しようとしている場合、または同じコマンドを複数回実行しようとしている場合は、for ループは間違いなくその仕事に適したツールです。

[次のこともお勧めします:AnsibleでJinjaテンプレートを使用してループをマスターする]

プログラミングまたはスクリプトのバックグラウンドがすでにある場合は、forに精通している可能性があります。 ループはありません。そうでない場合は、わかりやすい英語で分解してみます。

基本的な概念は次のとおりです。FOR 特定のアイテムのセット、実行 事。

指定されたアイテムのセットは、文字通りのオブジェクトのセット、またはBashがリストに推定できるものであれば何でもかまいません。たとえば、ファイルから取得したテキスト、別のBashコマンドの出力、コマンドラインから渡されたパラメータなどです。このループ構造をBashスクリプトに変換することも簡単です。この記事では、forの例をいくつか紹介します。 ループを使用すると、コマンドラインヒーローのように見せることができます。次に、それらの例をいくつか取り上げて、より構造化されたBashスクリプト内に配置します。

forループの基本構造

まず、forの基本構造について説明しましょう。 ループしてから、いくつかの例を見ていきます。

forの基本構文 ループは次のとおりです:

for <variable name> in <a list of items>;do <some command> $<variable name>;done;

変数名 doで指定する変数になります セクションが表示され、ループ内のアイテムが含まれます。

アイテムのリスト スペースまたは改行で区切られたリストを返すものであれば何でもかまいません。

次に例を示します:

$ for name in joey suzy bobby;do echo $name;done

それは簡単で、それほど多くのことは行われていませんが、それで始められます。変数$name ループが現在動作しているリスト内のアイテムが含まれ、do内の1つまたは複数のコマンドが含まれます セクションが実行されると、ループは次のアイテムに移動します。ループごとに複数のアクションを実行することもできます。 doの間のすべて およびdone 実行されます。新しいコマンドには;が必要です それらを区切る。

$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby

さて、いくつかの本物 例。

ファイルの名前変更

このループは、Bashコマンドの出力を受け取りますls *.pdf 返された各ファイル名に対してアクションを実行します。この場合、今日の日付をファイル名の最後に追加します(ただし、ファイル拡張子の前に追加します)。

for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done

説明のために、これらのファイルを含むディレクトリでこのループを実行します。

file1.pdf
file2.pdf
...
fileN.pdf

ファイルの名前は次のように変更されます:

file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf

何百ものファイルがあるディレクトリでは、このループにより、すべてのファイルの名前を変更する時間を大幅に節約できます。

アイテムのリストの外挿

scpしたいファイルがあると想像してください。 複数のサーバーに。 forを組み合わせることができることを忘れないでください シェル拡張などの他のBash機能とループします。これにより、Bashは一連のアイテムのリストを拡張できます。これは、文字と数字に対して機能します。例:

$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10

サーバーにweb0のようなパターンで名前が付けられていると仮定します。 、 web1 web2 web3 、Bashに次のように一連の数値を反復させることができます:

$ for i in web{0..10};do scp somefile.txt ${i}:;done;

これはweb0を反復処理します 、 web1 web2 web3 、など、各アイテムに対してコマンドを実行します。

いくつかの反復を定義することもできます。例:

$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c

反復を組み合わせることもできます。米国とカナダに2つのデータセンターがあり、サーバーの命名規則によって、サーバーのHAペアが存在するデータセンターが特定されているとします。たとえば、 web-us-0 web-ca-0 は、米国のデータセンターで最初のWebサーバーになります。 Web0のになります CAデータセンターのカウンターパート。両方のシステムで何かを実行するには、次のようなシーケンスを使用できます。

$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3

サーバー名を簡単に繰り返すことができない場合は、名前のリストをforに提供できます。 ループ:

$ cat somelist
first_item
middle_things
foo
bar
baz
last_item

$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item

ネスト

これらのアイデアのいくつかを組み合わせて、より複雑なユースケースにすることもできます。たとえば、前の例で使用した番号付きの命名規則に従って、ファイルのリストをWebサーバーにコピーするとします。

これは、ネストされたループを介して最初のリストに基づいて2番目のリストを繰り返すことで実現できます。ワンライナーとしてやっていると、これを理解するのは少し難しくなりますが、間違いなく行うことができます。ネストされたfor ループは、親のforの反復ごとに実行されます ループ。ループごとに異なる変数名を指定してください。

ファイルのリストをコピーするにはfile1.txt、file2.txt、 およびfile3.txt Webサーバーに対して、このネストされたループを使用します:

$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3

よりクリエイティブな名前の変更

これを行うには他の方法もあるかもしれませんが、これはできることの単なる例であることを忘れないでください forで行う ループ。 FILE002.txtのような名前のファイルが山ほどある場合はどうなりますか 、およびファイルを置き換えたい TEXTのようなもので 。 Bash自体に加えて、sedなどの他のオープンソースツールも自由に使用できることを忘れないでください。 、grep 、 もっと。これらのツールをforと組み合わせることができます このようにループします:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done

$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

Bashスクリプトにforループを追加する

forを実行しています コマンドラインで直接ループすることは素晴らしいことであり、いくつかのタスクのためにかなりの時間を節約します。さらに、forを含めることができます パワー、読みやすさ、柔軟性を高めるために、Bashスクリプトの一部としてループします。

たとえば、次のように、ネストされたループの例をBashスクリプトに追加して、読みやすさを向上させることができます。

$ vim copy_web_files.sh
# !/bin/bash

for i in file{1..3};do
  for x in web{0..3};do
    echo "Copying $i to server $x"
    scp $i $x
  done
done

このスクリプトを保存して実行すると、上記のネストされたループの例を実行した場合と同じ結果になりますが、読みやすくなり、変更や保守も簡単になります。

$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3

forの柔軟性と再利用性を高めることもできます パラメータ入力を可能にするBashスクリプトにそれらを含めることによってループします。たとえば、例のようにファイルの名前を変更するにはよりクリエイティブな名前変更 上記でユーザーが名前の接尾辞を指定できるようにするには、次のスクリプトを使用します:

$ vim rename_files.sh
# !/bin/bash

source_prefix=$1
suffix=$2
destination_prefix=$3

for i in $(ls ${source_prefix}*.${suffix});do
  mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done

このスクリプトでは、ユーザーは最初のパラメーターとしてソースファイルのプレフィックス、2番目のパラメーターとしてファイルのサフィックス、3番目のパラメーターとして新しいプレフィックスを指定します。たとえば、 FILEで始まるすべてのファイルの名前を変更するには 、タイプ .txt テキストへ 、次のようなスクリプトを実行します:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ bash rename_files.sh FILE txt TEXT

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

これは元の例と似ていますが、ユーザーが他のパラメーターを指定してスクリプトの動作を変更できるようになりました。たとえば、 TEXTで始まるすべてのファイルの名前を変更するには 新規へ 、以下を使用してください:

$ bash rename_files.sh TEXT txt NEW

$ ls NEW*.txt
NEW0.txt  NEW10.txt  NEW1.txt  NEW2.txt  NEW3.txt  NEW4.txt  NEW5.txt  NEW6.txt  NEW7.txt  NEW8.txt  NEW9.txt

[無料コース:仮想化とインフラストラクチャの移行の技術概要。 ]

結論

うまくいけば、これらの例はforの力を示しています Bashコマンドラインでループします。ループを使用すると、実際に多くの時間を節約し、エラーが発生しにくい方法でタスクを実行できます。ただ注意してください。ループは、論理ボリュームや仮想ディスクの作成(または削除)など、誤って破壊的なことをするように依頼した場合でも、依頼したとおりに実行されます。

Bashがforであることを願っています ループは、私たちの世界を変えたのと同じようにあなたの世界を変えます。


Linux
  1. KaliLinuxでのNmapの概要

  2. LinuxでのBash履歴の解析

  3. Linuxスクリプト:Bashでのwhileループの3つのハウツー

  1. Bashでループを作成する方法

  2. Linux シェル スクリプト用の 12 の Bash for ループの例

  3. Linux PDF バージョン コンバーター

  1. LinuxでBashプロンプトをWinterize

  2. Cプログラミング言語-はじめに

  3. Linux バッシュ。 for ループと関数、数値の加算