쌍을 이루는 라인 추출

쌍을 이루는 라인 추출

이런 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:, 두 번째 줄은 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:(.*)'

관련 정보