awk를 사용하여 특정 번호 뒤에있는 모든 열을 인쇄하는 방법은 무엇입니까?


답변:


82
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

3
몇 가지 약간의 개선 :awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman

감사합니다 @glenn, 실제로 좀 더 일반적입니다. 어쨌든 - 나는 그것을 사용하는 것이 좋을 것 확실히 동의 것 cut또는 perl이를 위해. 당신이 정말로 그것을 가지고 있다고 주장하는 경우에만 이것을 사용하십시오 awk.
Amadan

1
@SiegeX : NUL 바이트를 추가하지 않고 각 빈 필드 사이에 FS를 둡니다.
추후 공지가있을 때까지 일시 중지되었습니다.

1
우아함에 대한 @Ascherer의 답변을 참조하십시오.

3
@veryhungrymike : 우아함은 좋지만 나는 옳은 편입니다. : p
Amadan

68

다양한 필드를 수행하려는 awk경우이 작업을 수행하는 직접적인 방법이 없습니다. cut대신 다음을 권장 합니다.

cut -d' ' -f 9- ./infile

편집하다

기본값이 탭이기 때문에 공백 필드 구분 기호를 추가했습니다. 이것을 지적 해준 Glenn에게 감사합니다.


15
cut에 대한 한 가지는 awk가 "공백"을 사용하는 특정 구분 기호 (기본적으로 탭)를 사용한다는 것입니다. 잘라내기를 사용하면 연속 된 2 개의 탭이 빈 필드를 구분합니다.
glenn jackman

1
@glennjackman이 지적했듯이 awk의 구분 기호는 "공백"(모든 양)입니다. 따라서 잘라 내기 구분 기호를 단일 공백으로 설정하면 동작도 일치하지 않습니다. 불행히도 루프는 할 수있는 최선의 방법이므로 보입니다.
poncha

이것은 제대로 작동하지 않습니다. 명령을 시도하십시오 find . | xargs ls -l | cut -d' ' -f 9-. 어떤 이유로 이중 공백도 계산됩니다. 예 : lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_b결과는 다음과 같습니다./file_a 00:06 ./file_b
Marco Pashkov

@MarcoPashkov에 자세히 설명해 제대로 작동하지 않습니다 이것은 특히 당신이 사용을 고려, 정확한 파이프 라인에 동일한 코드를. 그건 그렇고, 당신은해야 LS의 출력을 구문 분석하지 마십시오
SiegeX

컷은 여기서 일을하지 않습니다. 예를 들어, 입력이 한 줄에 대해 "foo bar"(단일 공백)이고 다른 줄에 대해 "foo ___ bar"(즉, 여러 공백이지만 너무 똑똑해서 표시 할 수 없음) 인 경우 cut은 다른 방식으로 처리합니다.
UKMonkey

54
awk '{print substr($0, index($0,$9))}'

편집 : 참고, 9 번째 이전의 필드에 9 번째와 동일한 값이 포함 된 경우이 기능이 작동하지 않습니다.


3
이것은 훌륭합니다!

10
@veryhungrymike : ... 9 번째 이전의 필드에 9 번째와 동일한 값이 포함되어 있으면 작동하지 않습니다.
Amadan

6
아마도 고전적인 문장 인 "당신의 파일에 그런 문제가 없길 바랍니다." 다음과 같이 말하는 것은 소프트웨어 엔지니어링 분야에서 완전히 금지 되어 있습니다. "예를 들어 음수 값 입력에 대한 오류 검사를 포함하여 시간을 낭비하지 않을 것입니다. 왜냐하면 '사용자가 시도하지 않을만큼 충분히 지능적이기를 바랍니다. 도구 충돌 ' ". 하하하! 항상 이것을 듣고 싶어! (저는 유머 감각이 좋습니다) 글쎄, 바보 존재하기 때문에 그의 물건을 바보로부터 보호 하는 것이 개발자의 의무입니다 ! "사람의 선을 바라는 것"대신. 그것은 오히려 S / W 엔지니어가 아닌 철학자들에게 기대되는 태도입니다 ... LOL
syntaxerror

3
나는 오류를 확인하지 말라고 말한 것이 아니지만 문제가 발생하지 않을 것이라는 것을 알고 있다면 내가 말했듯 이이 솔루션은 괜찮습니다. 그러나 불필요한 반대 투표 @syntaxerror에 감사드립니다. 이 솔루션은 (현재) 19 개의 upvotes가 표시되므로 일부에게는 작동하지만 그렇지 않은 경우 솔루션에 사용하지 마십시오. OP의 문제를 해결하는 방법에는 여러 가지가 있습니다.
Ascherer 2014

1
일상 업무에서 명령 줄에서 awk를 사용하는 경우 이것이 확실히 원하는 솔루션입니다. 분명하지 않습니까? 오류 검사 등은 입력 중이며 Enter 키를 누르기 전에 이러한 종류의 것을 잡을 수 있기 때문에 실제로 중요하지 않습니다. (개인적으로는 awk를 다른 용도로 사용해서는 안된다고 생각합니다. Perl, python, tcl 및 약 100 개 이상의 기타, 더 좋고, 빠르며, 덜 성가신 스크립팅 언어가 있습니다!) '당연히 동료 소프트웨어 개발자에게 너무 많은 신용을주고 입력하는 내용에 대해서도 오류 검사가 필요합니다. 즉시 (??)
osirisgothra

11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

가변 너비 공백을 처리하는 대신 모든 공백을 단일 공백으로 바꿉니다. 그런 다음 cut관심 분야와 함께 간단하게 사용하십시오.

awk를 사용하지 않으므로 관련성이 없지만 다른 답변 / 댓글을 고려할 때 적절 해 보였습니다.


1
답변을 더 철저히 작성하십시오. 그렇지 않으면 질문에 대한 의견으로 게시하십시오.
Alper Turan 2015

이것은 ps faux | 사용하기에 이상적입니다 . XYZ 도구가 가장 적절하지 않다는 것을 인정하는 것을 두려워하지 마십시오.
kevinf

10

일반적으로 perl은 awk / sed / grep 등을 대체합니다. al., 훨씬 더 휴대 성이 뛰어납니다 (더 나은 주머니칼 일뿐만 아니라).

perl -lane 'print "@F[8..$#F]"'

물론 Timtowtdi가 적용됩니다.


명령 줄 옵션을 추가 -l하거나 \nprint 문에 추가 해야합니다.
glenn jackman

@glenn jackman : 아마도. 다른 메시지의 일부이거나 변수 등에 할당되는 경우에는 필요하지 않습니다. "더 좋음"에 관한 한, 펄은 확실히 작은 쪽에서 더 좋아 보입니다. 분명히 큰 것은 매우 어수선 해 보일 수 있습니다.
bobbogo

오해하지 마십시오. 저는 Perl을 좋아합니다. 나는 그것이 무엇인지에 대해 awk를 좋아합니다.
glenn jackman

내 임베디드 장치에는 Perl이 제공되지 않지만 awk가 있습니다.
Sepero

질문이 perl, ruby, java, python, bash가 아닌 awk에서 이것을 수행하는 방법을 물었 기 때문에 반대 투표.
Tom Harrison

3
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

이것은 주어진 필드 nr., N 앞에있는 것을 자르고, 필드 nr.N을 포함하고 원래의 간격을 유지하는 (재 형식화하지 않음) 나머지 라인을 모두 인쇄합니다. 필드의 문자열이 줄의 다른 어딘가에도 나타나는 경우에는 문제가되지 않으며 이는 Ascherer의 대답의 문제입니다.

함수 정의 :

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

다음과 같이 사용하십시오.

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

출력은 후행 공백을 포함하여 모든 것을 유지합니다. N = 0의 경우 전체 행을 그대로 반환하고 n> NF의 경우 빈 문자열을 반환합니다.


이것은 좋은 생각입니다. $ 0가 쓰러지기 때문에 일반적인 gawk를 사용하는 현재 Mac에서는 제대로 작동하지 않습니다. 수정은 첫 번째 단계로 변수를 $ 0으로 설정하는 것입니다. 예를 들면 다음과 같습니다. '{s = $ 0; ... 인쇄 SUBSTR (S, 인덱스 (S, M) +1}
joelparkerhenderson

1

다음은 ls -l출력 의 예입니다 .

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

게시물을 인쇄하는 내 솔루션 $9awk '{print substr($0, 61, 50)}'



0

처음 3 개 필드를 표시하고 나머지 필드를 인쇄하려면 다음을 사용할 수 있습니다.

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

여기서 $ 1 $ 2 $ 3은 처음 3 개 필드입니다.


0
function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

0

awk 대신 cut을 사용하고 -c 문자 cut 명령을 사용하여 시작할 열을 파악하는 문제를 해결합니다.

여기서는 출력의 처음 49자를 제외하고 모두 제공합니다.

 ls -l /some/path/*/* | cut -c 50-

/*/*/ls 명령의 끝에도 하위 디렉토리에 어떤 쇼 저를 말하고있다.

특정 범위의 문자 ala를 꺼낼 수도 있습니다 (잘라낸 맨 페이지에서). 예를 들어 현재 로그인 한 사용자의 이름과 로그인 시간을 표시합니다.

       who | cut -c 1-16,26-38
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.