pbm identification
As you know sed is a line oriented stream editor, so when the decision to print or not to print lies in another line like in this your case, we need to orchestrate a state machine, and they will need flip flops or variables in this case.
Essentially we need to hold back printing till we see the correct state transition. Like in this case, when we transition from state (email line) -> state(passwd line) only.
Using GNU sed
in extended regex mode -E
, which makes reading the sed code easier and writing it less prone to backslashitis.
$ sed -Ee '
/^PASSWORD:/!{h;d;}
x;G;s/(^|\n)[^:]*:/\1/g
' test.txt
Basic idea is to save the line which isn't a password line in the hold register so that when we actually get to the password line we can use it.
Using GNU awk
we essentially code the above sed functionality in awk with the awk variable e serving as the hold register.
$ awk -F: '
/^PASSWORD:/&&
($0=e RS $2)"";{e=$2}
' test.txt
Using GNU grep
we use the before option -B
to list one line before the password line then remove the dash line generated by grep and assume nobody uses that as a password.
$ < test.txt \
grep -B1 '^PASSWORD:' |
grep -Fxve -- | cut -d: -f2-
perl
can be used as shown when we pick the next line and then checks made.
$ perl -ne '
/^EMAIL:/ && ($_ .= <>);
/\nPASSWORD:/ && print(s/^[^:]+://mgr);
' tes.txt
bash builtins
while IFS=: read -r a p; do
case $a in
'PASSWORD') printf '%s\n' "$e" "$p" ;;
*) e=$p ;;
esac
done < test.txt
:
exist in any of the fields? – Ed Morton Sep 01 '20 at 12:20