2013-05-14 2 views
0

몇 가지 조작이 필요한 대용량 데이터베이스 파일이 있습니다. 본질적으로 나는 '|'로 구분 된 중복 된 필드 하나를 피할 필요가있다. 를 위해 :awk - 중복 행의 첫번째 줄과 그 아래의 행만 인쇄하십시오.

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA1 | SAME  |  | blah | blah 
ELIGIBLE | x2 
DATA1 | SAME  |  | blah | blah blah 
ELIGIBLE | x2 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA2 | SAME  |  | blah | blah 
ELIGIBLE | y2 
DATA2 | SAME  |  | blah | blah blah blah blah 
ELIGIBLE | y2 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1 
DATA3 | SAME  |  | blah | blah 
ELIGIBLE | z2 
DATA3 | SAME  |  | blah | blah blah blah blah 
ELIGIBLE | z2 

내가 사용하고있는 코드는

BEGIN{ FS = "|" } 
{ 
count[$1]++; 
if (count[$1] == 1) 
first [$1] = $0; 
if (count[$1] > 1) 
print first[$1] 
NR==1; 
} 

입니다 그러나 그것은 나에게 출력을 제공합니다

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1 
:이 같은 출력을 선호

-- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 
----------|----------|-----|------|--------------- 
-- 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
DATA3 | SAME  |  |  | blah blah 

제목 블록은별로 신경 쓰지 않지만 n 설명 된대로 데이터를 표시합니다. 아마추어 설명 미안하지만 솔루션에 대한 도움을 주시면 감사하겠습니다. 저는 리눅스 커맨드 라인 스크립팅에 관해서는 초보자입니다. 그래서 어떤 사람이 내 대답이 틀린 이유를 설명 할 수 있다면, 나는 많이 감사 할 것입니다. awk에 국한되지 않고 모든 명령 솔루션을 사용할 수 있습니다. 난 그냥 awk로 솔루션을 시도 싶었어요.

+0

그래서 당신이 나머지를 주어진 TITLE1와 데이터의 첫 번째 라인을 유지하고 버리고 싶은, 서로 다른 TITLE5의 등을하는 경우에도? –

+0

올바른지, 그 아래에 적합한 라인을 유지하십시오. –

답변

0

이 작업을 시도 할 수 :

awk -F\| '(printed!=0 && /ELIGIBLE/) {print; printed=0;} (!seen[$1] && $1 !~ /ELIGIBLE/) { print; printed = 1; seen[$1] = 1; }' 

을 거의 확실하게 더 나은 방법이 있지만.

도착 시간 : 좋은 Awk 튜토리얼 here 및 기타 여러 권의 웹이 좋은 책과 함께 제공됩니다. 그러나 기본적으로 awk 프로그램은 패턴과 일치하는 모든 레코드 (기본적으로 행)에서 실행되는 일련의 패턴 및 코드 블록입니다.

awk '/foo/   { do this for lines that contain "foo" anywhere } 
    ($1 == "bar") { do this for lines whose first field is exactly "bar' } 
    ($NF ~ /baz/) { do this for lines whose last field contains "baz" } 
    (NF == 1)  { do this for lines with exactly one field } 
    (NR == 10)  { do this only on the 10th line }' 

패턴이없는 경우 블록은 모든 줄에서 실행됩니다. 어떤 블록 단지 패턴이없는 경우

awk '{print $NF}' # print the last field of every line 

다음 매칭 라인이 그대로 출력된다

awk '/foo/'  # same as grep foo 

모든 입력이 처리되기 전에 실행 BEGIN 표시된 블록; 모든 입력이 처리 된 후 END로 표시된 블록이 실행됩니다.

awk 'BEGIN { t = 0 } {t += $NF} END { print t }' # print total of last column 

실제로 초기화되지 않은 변수는 연산에서 0으로 처리됩니다, 그래서 당신은 초기화 건너 뛸 수 : AWK의

awk '{t += $NF} END {print t}' 

일부 버전은 패턴/블록 쌍 사이의 세미콜론 ; 또는 줄 바꿈을 필요로를

+0

이 솔루션은 완벽하게 작동합니다. 정말 고마워요! awk를 사용하여 텍스트를 제외/포함하는 방법을 설명해 주시겠습니까? 죄송합니다. 배우고 있으며 필드 일치에만 사용했습니다. –

+0

이 질문에 대한 답변을 수락해야합니다 ... –

0

이 행은 주어진 예제에서 작동합니다. (데이터 정렬, 온라인 데이터, 온라인 적용 가능 ...) 형식이 변경되면 실제 데이터에 대한 작업이 보장되지 않습니다. 너 혼자 시험해야 해.

제목/헤더를 건너 뜁니다.

awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file 

그것을 시도 :

kent$ awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file 
DATA1 | SAME  |  |  | blah blah 
ELIGIBLE | x1 
DATA2 | SAME  |  |  | blah blah 
ELIGIBLE | y1 
DATA3 | SAME  |  |  | blah blah 
ELIGIBLE | z1 
관련 문제