세 번째 열을 마지막 열로 인쇄하는 방법은 무엇입니까?


답변:


108

... 또는 더 간단한 해결책 : cut -f 3- INPUTFILE 올바른 구분 기호 (-d)를 추가하면 동일한 효과를 얻을 수 있습니다.


9
구분 기호가 모든 열에서 정확히 동일한 경우에만 작동합니다. 예를 들어 \ d +와 같은 구분 기호와 함께 cut을 사용할 수 없습니다. (내가 알고 있음)
Zach Wily

72
질문 제목이 awk 인 경우 awk 이외의 답변을 수락하는 것은 부적절합니다. 사람들이 awk 스크립트에 필요하면 어떨까요? 이 대답은 그냥 주석이었을 것입니다.
syaz

24
@SyaZ : 일반적으로 동의하지만,이 게시판에 '무의미한 awk'의 양이 올라감에 따라 작업을 수행하는 다른 방법을 보여줄 필요가 있다고 생각했습니다. 누군가가 같은 작업을 더 간단하고 빠르게 수행하는 방법을 보여 주면 감사하지 않겠습니까? 아마도 포스터는 awk가 다른 질문에 대한 '잘못된 것은 아니지만 확실히 즉흥적 인'답변 때문에 이것을하는 유일한 방법이라고 생각했을까요?
Marcin

12
그것이 주석의 목적입니다. 가장 좋은 awk 대답을 받아들이고 댓글에 대해 더 나은 awk 제안을 제공하십시오. 사람들이 질문에 정확히 답하지 않는 답변을 게시하기 시작하면 검색 할 때 짜증이 날 것입니다 (제 경우).
syaz 2010

12
구분 기호는 모든 열간에 동일해야 할뿐만 아니라 열 사이에 정확히 하나의 구분 기호가 있어야합니다. 따라서 출력을 구분 기호로 정렬하는 프로그램을 다루는 경우 awk를 사용하는 것이 좋습니다.
sknaumov

112
awk '{for(i=3;i<=NF;++i)print $i}' 

3
awk '{for (i = 3; i <= NF; ++ i) print $ i}'는 더 간결합니다. :)
user172818

1
고마워, lh3. 그냥 gawk 매뉴얼을 복사해서 붙여넣고 있었어요. :)
Jonathan Feinberg

23
이것은 인쇄 iwth 인쇄 할 때마다 열이 새로운 라인으로 백토되어, 여러 라인 실패
meso_2600

13
분할 된 출력 문제를 해결하기 위해이 솔루션을 제안합니다. awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}'( 다른 필드가 인쇄 된 후 printf개행 문자를 print ""추가 하는 동안 개행 문자를 인쇄하지 않음 )
lauhub

1
또는 : echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}', 이는 다음을 제공합니다 3 4 5 6 7 8 9 10..
x-yuri

106
awk '{ print substr($0, index($0,$3)) }'

해결책은 여기에서 찾을 수 있습니다 :
http://www.linuxquestions.org/questions/linux-newbie-8/awk-print-field-to-end-and-character-count-179078/


23
약간 늦었지만 첫 번째 또는 두 번째 필드가 세 번째 필드 (예 : 3 2 3 4 5)와 같은 레코드에는 작동하지 않습니다.
aleph_null

내부 범위를 인쇄하는 것도 가능합니다 :```# $ 3 (포함)에서 $ 6 (제외); 에코 "1,2,3,4,5,6,7,8,9"| awk 'BEGIN {FS = ","; OFS = ","} {print substr ($ 0, index ($ 0, $ 3), length ($ 0) -index ($ 0, $ 6) -1)}'; # 3,4,5''` 제공
splaisan

34

Jonathan Feinberg 의 답변은 각 필드를 별도의 줄에 인쇄합니다. 을 사용 printf하여 동일한 행에 출력 할 레코드를 다시 작성할 수 있지만 필드를 왼쪽으로 이동하면됩니다.

awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile

1
이것은 Gnu awk에서만 작동하며 NFPOSIX 에서는 감소 가 허용되지 않습니다.
kvantour

1
@kvantour : gawk, mawk, MacOS awk (nawk?)에서 작동합니다. POSIX는 NF감소 가능 여부에 대해 침묵하는 것처럼 보입니다 .
추후 공지가있을 때까지 일시 중지되었습니다.

그것은 awk 의 이러한 재미있는 어두운 구석 중 하나입니다 .
kvantour

19
awk '{$1=$2=$3=""}1' file

주의 :이 방법은 1,2,3 필드에 "공백"을 남기지 만 출력 만보고 싶다면 문제가되지 않습니다.


`| sed s / ^ \ * // | 열 -t` 남은 열을 공백 주요 스트립과 정렬하기
MSpreij

마지막 1은 무엇을 의미합니까? 어떤 키워드로 검색해야 awk합니까?
Itachi


1
당신 @Nathan으로이 문제를 해결{$1=$2=$3="";$0=$0;$1=$1}1
kvantour

11

예를 들어 같은 줄에서 세 번째 이후의 열을 인쇄하려면 다음을 사용할 수 있습니다.

awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}'

예를 들면 :

Mar 09:39 20180301_123131.jpg
Mar 13:28 20180301_124304.jpg
Mar 13:35 20180301_124358.jpg
Feb 09:45 Cisco_WebEx_Add-On.dmg
Feb 12:49 Docker.dmg
Feb 09:04 Grammarly.dmg
Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf

다음과 같이 인쇄됩니다.

20180301_123131.jpg
20180301_124304.jpg
20180301_124358.jpg
Cisco_WebEx_Add-On.dmg
Docker.dmg
Grammarly.dmg
Payslip 10459 %2828-02-2018%29.pdf

보시다시피, 급여 명세서는 공백이 있어도 올바른 줄에 표시됩니다.


빠르고 매끄 럽습니다. 감사합니다;)
9nz9 aug

$ NF가 제외되는 문제를 제외하고는 훌륭합니다. 조건 (<= NF)을 설정하면 마지막 필드가 표시되지만 첫 번째 필드의 첫 번째 문자가 잘립니다. 기능 측면에서 오해가 있습니까?
Ken Ingram

내 문제는 ^ M이 마지막 열 끝에 붙어 있다는 것입니다. 그것을 제거하는 방법을 보지 마십시오.
Ken Ingram

8

다음 줄은 어떻습니까?

awk '{$ 1 = $ 2 = $ 3 = ""; print} '파일

@ ghostdog74 제안을 기반으로합니다. 내 라인을 필터링 할 때 더 잘 작동해야합니다.

awk '/ ^ exim4-config / {$ 1 = ""; } '파일 인쇄

짧고 간단합니다. 또한 sed 's/\s\+//g'명령 끝에 파이프 및 추가 하여 선행 공백을 다듬을 수 있습니다.
jumping_monkey

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

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

함수를 정의하십시오.

fromField () { 
awk -v m="\x0a" -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'이 레코드 구분 기호 인 파일에 잘 작동하므로 줄 안에 줄 바꿈 문자가 없습니다. 다른 레코드 구분 기호와 함께 사용하려면 다음을 사용하십시오.

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

예를 들면. 16 진수 문자 번호를 사용하지 않는 한 거의 모든 파일에서 잘 작동합니다. 라인 안에 1 개.


4

다음 awk 명령은 각 줄의 마지막 N 개 필드를 인쇄하고 줄 끝에 새 줄 문자를 인쇄합니다.

awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'

아래에서 / usr / bin 디렉토리의 내용을 나열하고 마지막 3 개 행을 보유한 다음 awk를 사용하여 각 행의 마지막 4 개 열을 인쇄하는 예제를 찾으십시오.

$ ls -ltr /usr/bin/ | tail -3
-rwxr-xr-x 1 root root       14736 Jan 14  2014 bcomps
-rwxr-xr-x 1 root root       10480 Jan 14  2014 acyclic
-rwxr-xr-x 1 root root    35868448 May 22  2014 skype

$ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Jan 14 2014 bcomps 
Jan 14 2014 acyclic 
May 22 2014 skype

4
awk '{a=match($0, $3); print substr($0,a)}'

먼저 세 번째 열의 시작 위치를 찾습니다. substr을 사용하면 위치 (이 경우 a)에서 시작하여 줄 끝까지 전체 줄 ($ 0)을 인쇄합니다.


3

음, 정규 표현식을 사용하면 동일한 효과를 쉽게 얻을 수 있습니다. 구분 기호가 공백이라고 가정하면 다음과 같습니다.

awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'

1
정규식을 피하고 싶습니다. 실수로 엉망으로 만드는 것이 더 느리고 쉬울 것입니다.
Cascabel

1
다음과 같이 짧아집니다 : awk '{ sub(/([^ ]+ +){2}/, ""); print }'패턴을 두 번 제거합니다.
erik


2

Perl 솔루션 :

perl -lane 'splice @F,0,2; print join " ",@F' file

다음 명령 줄 옵션이 사용됩니다.

  • -n 입력 파일의 모든 줄을 반복하고 모든 줄을 자동으로 인쇄하지 않음

  • -l 처리하기 전에 줄 바꿈을 제거하고 나중에 다시 추가합니다.

  • -a자동 분할 모드 – 입력 라인을 @F 배열로 분할합니다. 공백으로 분할하는 기본값

  • -e Perl 코드 실행

splice @F,0,2 @F 배열에서 열 0과 1을 깨끗하게 제거합니다.

join " ",@F 각 요소 사이에 공백을 사용하여 @F 배열의 요소를 결합합니다.

입력 파일이 공백으로 구분되지 않고 쉼표로 구분 된 경우 다음을 사용하십시오. -F, -lane


Python 솔루션 :

python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file


1

여기에서 조금 늦었지만 위의 어느 것도 작동하지 않는 것 같습니다. printf를 사용하여 각 사이에 공백을 삽입하십시오. 나는 끝에 개행을 사용하지 않기로 결정했습니다.

awk '{for(i=3;i<=NF;++i) printf("%s ",  $i) }'

1
awk '{for (i=4; i<=NF; i++)printf("%c", $i); printf("\n");}'

4 번째 필드부터 마지막 ​​필드까지 원본 파일과 동일한 순서로 레코드를 인쇄합니다.


죄송합니다. 정답이 아닙니다. 그것은 너무 구체적이다,하지만 난 그것을 삭제하는 방법을 모른다
마시모

1

Bash에서는 위치 매개 변수와 함께 다음 구문을 사용할 수 있습니다.

while read -a cols; do echo ${cols[@]:2}; done < file.txt

자세히 알아보기 : Bash Hackers Wiki에서 위치 매개 변수 처리


0

처음 두 필드를 무시하고 해당 필드를 마스킹 할 때 공백을 원하지 않는 경우 (위의 일부 답변처럼) :

awk '{gsub($1" "$2" ",""); print;}' file

0
awk '{$1=$2=""}1' FILENAME | sed 's/\s\+//g'

처음 두 개의 열이 지워지고 sed선행 공백이 제거됩니다.


-2

AWK에서 열은 필드라고하므로 NF가 핵심입니다.

모든 행 :

awk -F '<column separator>' '{print $(NF-2)}' <filename>

첫 번째 행만 :

awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.