bashを使用してcsvファイルを解析する方法

IPアドレスと開いているポートを含むCSVファイルがあります:

IP,1,3,4,6,7,9,13,17,19,20,21,22,23,24,25,26 1.1.1.2,,,,,,,,,,,open,,,,, 1.1.1.3,,,,,,,,,,,open,,,,, 1.1.1.4,,open ,open,,,,,,,,open,,,,, 1.1.1.5,,,,,,,,,,,open,,,,, 1.2.3.4,,,,,,,,,,,open,,,,, 1.4.5.6,,,,,open,,,,,,open,,,,, 1.4.5.6,,,,,,,,,,,open,,,,, 1.1.3.4,,,,,,,,,,,open,,,,, 

ポートが開いているIPアドレスごとに、IPアドレスと開いているポートのポート番号(CSVヘッダーから取得)の両方を使用してコマンドを実行する必要があります。

コメント

  • ポートが開いているIPごとに実行するコマンドは、対応するポート番号を使用する必要がありますか?ポート番号はCSVヘッダーに記載されている番号ですか?
  • @Kusalananda正確に!!
  • 質問の編集を手伝ってくれてありがとう@Kusalanandaそしてあなたは私の質問を理解しました
  • 'この特定の質問をお伝えします、ありがとうございます。ただし、答える場合は、'実行しているコマンドを知りたいので、'がポートの方法を明確にします。描写する必要があります。 ' dは、答えをより役立つものにすると思います。 ' dは、可能なポートの数が26で終わるのか、それとも65,535に達する可能性があるのかについても知りたいですか?また、開いているポートが 1つしかないのでしょうか。ゼロまたは複数ある可能性がありますか?
  • @JeffSchallerコマンドはtelnetであり、ポート番号は65,535までではありませんが、900を超えるポートがあり、スキャンごとにステータスが変化します。私が達成したいのは、アクティブなtelnetセッションがリッスンしているかどうかを確認することですが、開いているIPとポート番号を選択するのに助けが必要です

回答

これを完全に純粋なbashで解決することはお勧めできません。たとえば、質問「シェルループを使用してテキストを処理するのはなぜ悪い習慣だと考えられているのですか?」。

代わりに、入力データを作成しましょう。消化が少し簡単です。

awk "FNR == 1 { split($0, port, ","); FS=","; next } { for (i=2; i<=NF; ++i) if ($i == "open") print $1, port[i] }" file.csv 

このawkコマンドは、最初にの最初の行からポート番号を読み取ります。 CSVファイルをportという配列に格納します。列Nのポート番号はport[N]

これは、入力の最初の行をコンマで分割し、結果をport配列に格納することで行われます。これがsplit()コマンドは実行します。条件FNR == 1は、「これがファイルの最初の行である場合は、これを実行します…」(FNRは、現在の入力ファイルの行番号です。条件のないコードブロックは、入力の各行に対して実行されます。

、はコンマに設定されています。これは、ファイル内の他の行が自動的にコンマでフィールドに分割されることを意味します。これは、2番目のブロックのループで使用され、各行のCSVフィールド(2番目のフィールドから最後のフィールドまで)をループします。

データ内の他の各行について、コンマ区切りのフィールドをループし、値が文字列openであるフィールドを見つけると、 IPアドレス(最初のフィールド)と対応するポート番号を出力します。

問題のデータが与えられた場合のこのコマンドからの出力は

1.1.1.2 21 1.1.1.3 21 1.1.1.4 4 1.1.1.4 21 1.1.1.5 21 1.2.3.4 21 1.4.5.6 7 1.4.5.6 21 1.4.5.6 21 1.1.3.4 21 

これは、シェルのループで簡単に読み取ることができます。

while read -r ip port; do telnet "$ip" "$port" # or whatever your command is done 

これは、IPアドレスとポート番号を1つずつ読み取ります。

これらを完全なスクリプトに組み合わせるには:

#!/bin/sh awk "FNR == 1 { split($0, port, ","); FS=","; next } { for (i=2; i<=NF; ++i) if ($i == "open") print $1, port[i] }" file.csv | while read -r ip port; do telnet "$ip" "$port" # or whatever your command is done 

awkの出力コマンドは、値を読み取ってコマンドを呼び出すwhileループにパイプされます(入力ファイル名の後に|パイプがあることに注意してください)。

IPアドレスで複数のポートが開いている場合、コマンドはそのアドレスに対して複数回実行されることに注意してください。

コメント

  • OMGこれは私がtrだったものでしたやりたくて、これはすごい。私はばかげていますこれをもっと理解するのを手伝ってくれませんか(デバッグモードで教えてもらえますか?)
  • @biniyamgetu説明する必要があることを正確に知る必要があります。
  • Bro I本当にありがたいです、これはとても役に立ちます…だから、FNR == 1は何をしているのか、そして分割が表示され、FSは何ですか
  • @biniyamgetuちょっと待って、それらについていくつかのテキストを追加します。
  • あなたは天才で、私がやりたかったことをやっています…ありがとうございます!!

回答

awkを使用して最初と次のそれぞれのフィールドを選択します。

awk -d "," -F "{print $1, $n...} 

コメント

  • これはまだ'コマンドの実行やポートの使用に対応していません。将来的に、質問に大量のコメントや編集が行われる場合は、'要件が解決するのを待ってから、回答を試みることをお勧めします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です