이 파일이 있어요
john
robert
rose*
ann*
charles
david
liz*
louis
wendy*
kate*
mandy*
paul
'*' 앞의 줄을 제외한 모든 줄을 인쇄하고 싶으므로 원하는 출력은 다음과 같습니다.
john
rose*
ann*
charles
liz*
wendy*
kate*
mandy*
paul
나는 이전에 시도했습니다:
awk '/\*/ {f=1}; (!f &&NR > 1) {print p}; {p=$0;f=0} END {print p}' file
출력을 생성합니다
john
ann*
charles
liz*
mandy*
paul
코드에 문제가 있나요?
답변1
rose*
*
( ) 앞의 줄 ann*
이므로 기준이 I want to print all lines except those lines before '*'
예상 출력과 일치하지 않으며 코드가 말한 대로 수행되는 것처럼 보입니다.
*
대신 포함하는 line을 포함 및/또는 제외하는 모든 행을 인쇄하여 *
표시할 예상 출력을 얻으려면 다음과 같습니다.
$ awk '(NR>1) && ((p ~ /\*/) || !/\*/){print p} {p=$0} END{print p}' file
john
rose*
ann*
charles
liz*
wendy*
kate*
mandy*
paul
답변2
이것은 대부분 내 개인적인 즐거움을 위한 것입니다.
sed
동일한 문제를 해결하기 위한 명령:
sed -e 'N' -e '/[^*]$/P' -e '/[*]\n.*[*]$/P' -e '$!D' -e 's/.*\n//' file
그러면 편집 버퍼의 입력에서 두 줄이 남습니다. 다음 줄은 N
삽입된 리터럴 개행 문자에 의해 기존 데이터와 구분된 를 사용하여 편집 버퍼에 추가됩니다 sed
.
*
버퍼의 끝이 없으면 버퍼의 초기 부분이 인쇄됩니다 P
. 그 뒤에 별표가 없는 줄이 있으면 이것이 출력 줄의 내용입니다.
버퍼에 *
리터럴과 개행 문자가 포함된 경우(예: 버퍼의 첫 번째 부분이 로 끝남 *
)그리고*
버퍼 끝에 ; 가 있고 첫 번째 부분은 으로 인쇄됩니다 P
. 이는 별표 표시된 줄이 뒤에 오더라도 별표 표시된 줄을 출력하는 것입니다.
D
버퍼의 초기 부분은 끝에 도달하지 않으면 삭제됩니다. 또한 이 D
명령은 자동으로 스크립트가 첫 번째 명령에서 시작되도록 합니다(그러나 전체 편집 버퍼를 지우거나 자동으로 다른 입력 줄을 읽지는 않습니다 d
).
마지막 명령에 도달하면 s
마지막 줄을 읽은 것이고 마지막 두 줄은 버퍼에 있습니다. 여기서 첫 번째 줄은 이미 인쇄되어 있어야 합니다(또는 인쇄되지 않아야 함). 따라서 나머지 마지막 줄을 인쇄하기 전에 해당 줄을 제거해야 합니다.
더 짧은 변형:
sed -e '$q' -e 'N' -e '/[^*]$/P' -e '/[*]\n.*[*]$/P' -e 'D' file
D
이는 마지막 무조건 명령이 편집 버퍼에 남아 있는 끝에서 두 번째 줄도 잘라내고 $q
스크립트 시작 부분에서 단축되는 최종 반복을 허용하여 마지막 줄을 인쇄한 후 스크립트가 종료된다는 사실에 의존합니다 .
답변3
만약 그것이 sed
받아들여질 수 있다면
sed '/\*$/!{$!N;//!P;D;}' file
: 로 끝나지 않는 줄의 경우 다음 줄을 *
읽고 N
, 여전히 일치하는 항목이 없으면 첫 번째 줄을 인쇄합니다. D
첫 번째 행을 삭제하고 프로세스를 반복하십시오.