2013-04-17 2 views
0

테이블의 마지막 행에 필드를 추출하기위한 bash 스크립트를 작성하고 싶습니다. 나는 예시로 설명 할 것이다. 나는sed를 사용하여 주어진 테이블의 마지막 행에서 필드 추출하기

Table 1 (foobar) 
num flag name comments 
1 ON Frank this guy is frank 
2 OFF Sarah she is tall 
3 ON Ahmed who knows him 

Table 2 (foobar) 
num flag name comments 
1 ON Mike he is short 
2 OFF Ahmed his name is listed twice 

내가 3입니다 Table1의 마지막 행에서 첫 번째 필드를 추출 할 ... 같은 공간이 구분 된 필드와 테이블을 포함하는 텍스트 파일이 있습니다. 이상적으로 나는 이것을하기 위해 주어진 테이블의 제목을 사용할 수 있기를 원합니다. 각 테이블간에 캐리지 리턴이 보장됩니다. sed와 grep을 사용하여이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

+3

을 '와'grep'? 'awk'는 이런 종류의 일을하기 위해 만들어졌습니다. –

+0

대부분 학습 목적이지만 일관성을 위해서. 또한 awk가 반드시 필요하지 않은 컴퓨터로 포팅 될 수 있습니다. – user2150250

답변

4

awk는이 적합합니다, 각 레코드에 대해 마지막 행의 첫 번째 필드를 인쇄 :

$ awk '!$1{print a}{a=$1}END{print a}' file 
3 
2 

을 그냥 첫 번째 레코드에서 :

$ awk '!$1{print a;exit}{a=$1}' file 
3 

편집 :

주어진 테이블의 제목 :

$ awk -v t="Table 1" '$0~t{f=1}!$1&&f{print a;f=0}{a=$1}END{if (f) print a}' file 
3 

$ awk -v t="Table 2" '$0~t{f=1}!$1&&f{print a;f=0}{a=$1}END{if (f) print a}' file 
2 
+2

+1 "올바른"답변입니다. –

+0

+1하지만 * 완벽한 * 대답은 3 열 요구 사항을 하드 코딩하지는 않지만 :-) 우아한 방법을 아직 생각할 수는 없습니다! – cmbuckley

+0

@cbuckley 나는'$ awk '할거야! $ 1 {print a} {a = $ 1} END {print a}'file' –

-1

더 나은 도구가 awk입니다!

awk '{ 
    if(NR==1) { 
     row=$0; 
     next; 
    } 

    if($0=="") { 
     $0=row; 
     print $1; 
    } else { 
     row=$0; 
    } 
} END { 
    if(row!="") { 
     $0=row; 
     print $1; 
    } 
}' input.txt 
+0

downvote는 적어도 코멘트가 필요합니다 – jyz

+0

나는 동의합니다. 나는 아니었다. 어쨌든 답변 해 주셔서 감사합니다. – user2150250

+2

나도 아니지만 awk 커뮤니티는 까다 롭다. 그것은 더 간결 해 보인다.(편집 : 찾은 [찾았던 기사] (http://backreference.org/2010/02/10/idiomatic-awk/)) – cmbuckley

2

이 나오지 라인은 샘플을 위해 작동하는 것 같다 :
다음은 일종의 읽기 쉬운 코드입니다.

table='Table 2' 
sed -n "/$table"'/{n;n;:next;h;n;/^$/b last;$b last;b next;:last;g;s/^\s*\(\S*\).*/\1/p;}' file 

설명 : $ table에서 테이블 이름과 일치하는 행을 찾으면 해당 행과 다음 (필드 레이블)을 건너 뜁니다. 시작 위치 : 다음으로 현재 줄을 보류 공간으로 밀어 넣고 다음 줄을 가져 와서 파일의 끝이 공백인지 아니면 파일의 끝인지 확인합니다. 그렇지 않으면 다음으로 돌아갑니다. 다음으로 현재 줄을 누르고 다른 줄을 누릅니다. 공백 또는 EOF 인 경우 마지막으로 건너 뜁니다. 보류 공간 (테이블의 마지막 줄)을 패턴 공간으로 가져오고 첫 번째 필드를 제외하고 모두 잘라내어 인쇄하십시오.

+0

Wowwwww ... sed를 사용하여 이것을 해결하기 위해 +2를주고 싶습니다. 왜 awk가이 문제의 경우에 선호되는 방법인지 확실히 알 수 있습니다. – user2150250

+0

나는 sed의 큰 팬이다. 그러나 awk는 보통 이런 종류의 일에 더 좋다. 그래도 sed가 그렇게하도록 만드는 것은 재미 있습니다. – William

2

그냥 필드로 각 라인 기록으로 각 블록을 읽고 당신이 걱정하는 중 레코드의 마지막 필드의 첫 번째 서브 필드 인쇄 : 당신이 나오지`사용하려는 이유는 무엇

$ awk -v RS= -F'\n' '/^Table 1/{split($NF,a," "); print a[1]}' file 
3 

$ awk -v RS= -F'\n' '/^Table 2/{split($NF,a," "); print a[1]}' file 
2 
관련 문제