ペアのライン抽出

ペアのライン抽出

このようなtxtファイルがあります。行の合計email-passwordペアがありますemail-hash

EMAIL:[email protected]
PASSWORD:pass1
EMAIL:[email protected]
PASSWORD:pass2
EMAIL:[email protected]
PASSWORD:pass3
EMAIL:[email protected]
HASH:qwerty123
EMAIL:[email protected]
HASH:somehash
EMAIL:[email protected]
PASSWORD:pass6

email-password行が含まれていない行のみを抽出してみましたemail-hash。私の場合、コマンドは正しく機能しませんでした。sed -e 's/.*EMAIL://' -e 's/.*PASSWORD://' -e "/\b\HASH\b/d" test.txt

予想出力:

[email protected]
pass1
[email protected]
pass2
[email protected]
pass3
[email protected]
pass6

答え1

sed -n 'N;s/^EMAIL://;s/PASSWORD://p' file
  • Nパターン空間に次の行を追加し、
  • s/^EMAIL://他のものに置き換える必要はありませんEMAIL:
  • s/PASSWORD://p何も交換できPASSWORD:ません。交換が成功した場合のみ印刷

サンプル入力をテストします。仮定: 最初の行はEMAIL:、 2 番目の行は、PASSWORD:またはHASH:、その後繰り返します。


ボーナスとして空白行がある可能性がある場合は、awkを使用することをお勧めします。

awk -F ':' '/^PASSWORD:/{print line;print $2}/^EMAIL:/{line=$2}' file

答え2

プロジェクト管理の識別 ご存知のように、sedはライン指向のストリームエディタであるため、印刷するかどうかを他の行に依存する場合(たとえば、あなたの場合)、ステータスシステムを調整する必要があります。この場合、トリガーまたは変数が必要です。

デフォルトでは、正しい状態遷移が表示されるまで印刷を一時停止する必要があります。この例のように、ステータス(メール行) - >ステータス(パスワード行)からのみ切り替える場合です。

GNU sed拡張正規表現モードでは、-Esedコードを読みやすくし、バックスラッシュが少なくなる傾向があります。

$ sed -Ee '
    /^PASSWORD:/!{h;d;}
    x;G;s/(^|\n)[^:]*:/\1/g
' test.txt

デフォルトのアイデアは、パスワードラインではなくラインを保持レジスタに格納し、実際にパスワードラインに到達するときに使用できるようにすることです。

これを使用して、GNU awk基本的に上記のsed関数をawkに作成し、awk変数eを保持レジスタとして使用しました。

$ awk -F: '
    /^PASSWORD:/&&
    ($0=e RS $2)"";{e=$2}
' test.txt

GNU grepbeforeオプションを使用して-Bパスワード行の前に行をリストし、grepによって生成された点線を削除し、誰もそれをパスワードとして使用しないとします。

$ < test.txt \
  grep -B1 '^PASSWORD:' |
  grep -Fxve -- | cut -d: -f2-

perl次の行を選択して確認するときは、図のように使用できます。

$ perl -ne '
    /^EMAIL:/ && ($_ .= <>);
    /\nPASSWORD:/ && print(s/^[^:]+://mgr);
' tes.txt

バッシュ組み込み関数

while IFS=: read -r a p; do
  case $a in
    'PASSWORD') printf '%s\n' "$e" "$p" ;;
    *) e=$p ;;
  esac
done < test.txt

答え3

以下は、いくつかの追加のバリエーションです。

paste -d :  - - < myfile | awk -F: '$3 == "PASSWORD" {print $2; print $4}'
tac myfile | awk -F: '$1 == "PASSWORD" {print $2; getline; print $2}' | tac

答え4

ファイルが常にこの形式の場合、EMAIL他のすべての行の先頭に:

sed -n 'N;s/^EMAIL:\(.*\n\)PASSWORD:/\1/p'

それは行わなければなりません。または、安全のためにEMAIL:レコードの先頭を見つけます。

sed -n '/^EMAIL:/{N;s/^EMAIL:\(.*\n\)PASSWORD:/\1/p;}'

pcregrep複数行モードを使用することもできます。

pcregrep -M -o1 -o2 --om-separator=$'\n' '^EMAIL:(.*)\nPASSWORD:(.*)'

関連情報