このような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
拡張正規表現モードでは、-E
sedコードを読みやすくし、バックスラッシュが少なくなる傾向があります。
$ 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 grep
beforeオプションを使用して-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:(.*)'