正規表現の紹介 、私はそれらが何であるか、そしてなぜそれらが有用であるかをカバーしました。ここで、学習ツールとして使用する実際の例が必要です。これが私が数年前に出会ったものです。
この例では、Linuxコマンドライン、特に正規表現の、一般的なタスクを自動化する機能の能力と柔軟性を強調しています。私はキャリアの中でいくつかのメーリングリストを管理してきましたが、今でもそうしています。それらのリストに追加するために、人々は私に電子メールアドレスを送信します。複数のケースで、リストの1つに追加するMicrosoftWord形式の名前とメールアドレスのリストを受け取りました。
リスト自体はそれほど長くはありませんでしたが、フォーマットに一貫性がありませんでした。名前とドメインが変更された、そのリストの短縮版を次に示します。
Team 1 Apr 3
Leader Virginia Jones [email protected]
Frank Brown [email protected]
Cindy Williams [email protected]
Marge smith [email protected]
[Fred Mack] [email protected]
Team 2 March 14
leader Alice Wonder [email protected]
John broth [email protected]
Ray Clarkson [email protected]
Kim West [email protected]
[JoAnne Blank] [email protected]
Team 3 Apr 1
Leader Steve Jones [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]
Julie Lisbon [email protected]
[Mary Lastware) [email protected]
元のリストには、余分な行、削除する必要のある角かっこや括弧などの文字、スペースやタブなどの空白、およびいくつかの空の行が含まれていました。これらのメールをリストに追加するために必要な形式は、<first> <last> <[email protected]>
です。 。私たちの仕事は、このリストをメーリングリストソフトウェアで使用できる形式に変換することです。
リストに入力するための許容可能な形式にデータをマングルするために、データを操作する必要があることは明らかでした。テキストエディタまたはLibreOfficeWriterなどのワードプロセッサを使用して、この小さなファイルに必要な変更を加えることができます。しかし、このようなファイルはよく送られてくるので、ワープロを使って変更するのは面倒です。 Writerには優れた検索および置換機能がありますが、各文字または文字列を個別に置換する必要があり、以前の検索を保存する方法はありません。
Writerには強力なマクロ機能がありますが、私はその2つの言語であるLibreOfficeBasicまたはPythonのどちらにも精通していません。私はBashシェルプログラミングを知っています。
私はシステム管理者に自然に来ることをしました—私はタスクを自動化しました。最初に行ったのは、アドレスデータをテキストファイルにコピーして、コマンドラインツールを使用して作業できるようにすることでした。数分の作業の後、前の記事で示したBashコマンドラインプログラムを開発しました:
$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/\]//g" -e "s/)//g" | awk '{print $1" "$2" <"$3">"}' > addresses.txt
このコードは、ファイルaddresses.txt
として目的の出力を生成しました 。私は通常のアプローチを使用して、パイプラインを一度に1つのコマンドで構築することにより、このようなコマンドラインプログラムを作成しました。
このパイプラインを構成要素に分解して、どのように機能し、互いに適合するかを見てみましょう。このシリーズのすべての実験は、非特権ユーザーとして実行する必要があります。テスト用に作成したVMでもこれを行いました:studentvm1
。
まず、サンプルファイルを作成する必要があります。 testing
という名前のディレクトリを作成します ローカルマシンで、以下のテキストをExperiment_6-1.txt
という名前の新しいテキストファイルにコピーします。 、上記の3つのチームエントリが含まれています。
Team 1 Apr 3
Leader Virginia Jones [email protected]
Frank Brown [email protected]
Cindy Williams [email protected]
Marge smith [email protected]
[Fred Mack] [email protected]
Team 2 March 14
leader Alice Wonder [email protected]
John broth [email protected]
Ray Clarkson [email protected]
Kim West [email protected]
[JoAnne Blank] [email protected]
Team 3 Apr 1
Leader Steve Jones [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]
Julie Lisbon [email protected]
grepを使用して不要な行を削除する
私が最初にできることは、簡単なことです。チーム名と日付はそれ自体で行になっているため、次を使用して、「チーム」という単語が含まれる行を削除できます。
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team
このBashプログラムを構築する各段階の結果を再現することはしませんが、ターミナルセッションであるSTDOUTに表示されるデータストリームの変化を確認できるはずです。最後までファイルに保存しません。
データストリームを使用可能なものに変換するこの最初のステップでは、grep
を使用します 単純な文字パターンのコマンド、Team
。リテラルは、正規表現として使用できる最も基本的なタイプのパターンです。これは、検索対象のデータストリームに一致する可能性のあるものが1つだけであり、それが文字列Team
であるためです。 。
別のgrep
を使用できるように、空の行を破棄する必要があります それらを排除するためのステートメント。 2番目のgrep
の正規表現を囲むことがわかりました 引用符で囲まれたコマンドは、正しく解釈されることを保証します:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader Virginia Jones [email protected]
Frank Brown [email protected]
Cindy Williams [email protected]
Marge smith [email protected]
[Fred Mack] [email protected]
leader Alice Wonder [email protected]
John broth [email protected]
Ray Clarkson [email protected]
Kim West [email protected]
[JoAnne Blank] [email protected]
Leader Steve Jones [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]
Julie Lisbon [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$
式"^\s*$"
アンカーを示し、バックスラッシュ(\)をエスケープ文字として使用しています。 リテラル「s」(この場合)の意味を、スペース、タブ、または印刷できないその他の文字などの空白を意味するメタ文字に変更します。これらの文字はファイルに表示されませんが、一部含まれています。
アスタリスク、別名splat(*)は、0個以上の空白文字に一致することを示します。この追加は、複数のタブ、複数のスペース、または空の行にあるそれらの任意の組み合わせに一致します。
Vimで余分な空白を表示する
次に、表示されている文字を使用して空白を表示するようにVimエディターを構成しました。これを行うには、次の行を独自の~.vimrc
に追加します。 ファイル、またはグローバル/etc/vimrc
構成ファイル:
set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+
次に、Vimを起動または再起動します。
これを行う方法を検索したところ、インターネット上で多くの悪い、不完全な、矛盾した情報を見つけました。組み込みのVimヘルプには最高の情報があり、上記から作成したデータラインは私にとって有効なものです。
注: 以下の例では、通常のスペースは
+
として示されています。;タブは<
として表示されます 、<>
、または<–>
、およびタブがカバーするスペースの長さを埋めます。行末(EOL)文字は$
として表示されます 。
ファイルに対する操作の前の結果は、次のとおりです。
Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$
sedで不要な文字を削除する
ファイルから削除する必要のある空白文字がたくさんあることがわかります。また、2回表示され、1回大文字で表示される「リーダー」という単語を削除する必要があります。まず、「リーダー」を排除しましょう。今回はsed
を使用します (ストリームエディタ)一致するパターンを新しい文字列(この場合はnull文字列)に置き換えてこのタスクを実行します。
sed -e "s/[Ll]eader//"
を追加します パイプラインにこれを行います:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//"
このsed
コマンド、-e
引用符で囲まれた式が、目的の結果を生成するスクリプトであることを意味します。式では、s
これが代替であることを意味します。置換の基本的な形式は、s/<regex>/<replacement string>/
です。 、つまり/[Ll]eader/
は検索文字列です。
セット[Ll]
L
に一致 またはl
、つまり[Ll]eader
leader
と一致します またはLeader
。この場合、置換文字列はnullになります。これは、2つのスラッシュの間に文字や空白がない二重のスラッシュのように見えるためです(//
。
[]()
のような無関係な文字のいくつかも取り除きましょう それは必要ありません:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g"
sed
に4つの新しい式を追加しました 声明。それぞれが1つの文字を削除します。これらの追加の式の最初の式は少し異なります。これは、左の四角い中括弧([
)文字はセットの始まりをマークできます。 sed
を確実にするには、中括弧をエスケープする必要があります 特別な文字ではなく、通常の文字として正しく解釈します。
awkで片付け
sed
を使用できます 一部の行から先頭のスペースを削除しますが、awk
コマンドでそれを実行し、必要に応じてフィールドを並べ替えて、<>
を追加できます。 メールアドレスの周りの文字:
[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'
awk
ユーティリティは、実際には、STDINでデータストリームを受け入れることができる強力なプログラミング言語です。この事実により、コマンドラインプログラムやスクリプトで非常に役立ちます。
awk
ユーティリティはデータフィールドで機能し、デフォルトのフィールド区切り文字はスペース(任意の量の空白)です。これまでに作成したデータストリームには、空白で区切られた3つのフィールドがあります(<first>
、<last>
、および<email>
):
awk '{print $1" "$2" <"$3">"}'
この小さなプログラムは、3つのフィールド($1
)のそれぞれを取ります 、$2
、および$3
)そして、先頭または末尾の空白なしでそれらを抽出します。次に、それらを順番に印刷し、それぞれと<>
の間に1つのスペースを追加します。 メールアドレスを囲むために必要な文字。
ここでの最後のステップは、出力データストリームをファイルにリダイレクトすることですが、それは些細なことなので、そのステップを実行するのはあなたに任せます。そうする必要はありません。
Bashプログラムを実行可能ファイルに保存しました。これで、新しいリストを受け取ったときにいつでもこのプログラムを実行できます。この例のリストのように、これらのリストのいくつかはかなり短いものです。他のものは非常に長く、時には数百のアドレスと、リストに追加されるアドレスを含まない「もの」の多くの行が含まれています。
注: この記事は、私のLinuxの本の第2巻の第6章を少し変更したものです。Linuxの使用と管理:ゼロからSysAdminまで、2019年後半にApressからリリースされる予定です。