`cut`: 문자열이 포함된 열 선택

`cut`: 문자열이 포함된 열 선택

행당 여러 열이 있는 대용량 파일이 있습니다. cut -f -d숫자로 특정 열을 선택하는 데 익숙합니다 .

매뉴얼을 확인했는데 cut정규식 일치 열에 대한 방법이 없는 것 같습니다.

제가 구체적으로 하고 싶은 일은 다음과 같습니다.

  • 각 행의 두 번째 열 선택
  • "hello" 문자열이 포함된 모든 열을 선택합니다(아무 것도 아닐 수도 있고, 그렇지 않은 경우 임의의 열일 수 있으며 각 행마다 열이 다를 수 있음).

이를 수행하는 가장 편리한 터미널 도구는 무엇입니까?

편집하다:

단순화된 예

x ID23 a b c hello1
x ID47 hello2 a b c
x ID49 hello3 a b hello4
x ID53 a b c d

내가 원하는 결과는 다음과 같습니다.

ID23 hello1
ID47 hello2
ID49 hello3 hello4

또는:

ID23 hello1
ID47 hello2
ID49 hello3 hello4
ID53

주어진 예에 대한 자세한 설명:

  • 열은 공백으로 정의됩니다.
  • "문자열이 존재하는 경우에만 인쇄"인지는 중요하지 않습니다. grep필요한 경우 "hello"만 인쇄할 수 있습니다.
  • "hello"라는 문자열은 열 1이나 2에 전혀 나타나지 않는다고 가정할 수 있습니다.

답변1

줄 끝의 공백이 별로 영향을 미치지 않는 경우:

$ awk '{for(i=1;i<=NF;i++) if(i==2 || $i~"hello") printf $i" ";print ""}' file

ID23 hello1 
ID47 hello2 
ID49 hello3 hello4 
ID53 

이는 "hello" 문자열의 위치에 대해 어떠한 가정도 하지 않습니다.

답변2

cut또는 적어도 쉽지 않은 것을 사용하는 것 같습니다 . Perl 솔루션은 다음과 같습니다.

$ perl -lane '$k=join " ",grep{/hello/}@F; print "$F[1] $k" if $k' file 
ID23 hello1
ID47 hello2
ID49 hello3 hello4

먼저 다음을 사용하여 단순화할 수 있습니다 grep.

$ grep hello file | perl -lane 'print "$F[1] ", join(" ", grep{/hello/}@F)'
ID23 hello1
ID47 hello2
ID49 hello3 hello4

설명하다

-n옵션은 perl입력을 한 줄씩 읽고 주어진 스크립트를 적용하도록 지시합니다 -e. 이 플래그는 -l각 호출에 개행 문자( )를 추가합니다. 이 옵션은 공백의 입력 줄을 배열로 분할합니다.\nprint-aperl@F

따라서 스크립트 자체는 @F일치하는 모든 요소(모든 열)를 찾아 hello공백으로 구분된 문자열 $k( $k=join " ",grep{/hello/}@F;)로 저장합니다. 그런 다음 정의되어 있고 하나 이상이 발견되면 두 번째 필드( $F[1]) 및 를 인쇄합니다.$k$khello

$k두 번째 버전은 적어도 하나가 hello항상 존재한다는 것을 알기 때문에 직접 인쇄할 필요가 없다는 점을 제외하면 동일합니다 .

관련 정보