행당 여러 열이 있는 대용량 파일이 있습니다. 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
각 호출에 개행 문자( )를 추가합니다. 이 옵션은 공백의 입력 줄을 배열로 분할합니다.\n
print
-a
perl
@F
따라서 스크립트 자체는 @F
일치하는 모든 요소(모든 열)를 찾아 hello
공백으로 구분된 문자열 $k
( $k=join " ",grep{/hello/}@F;
)로 저장합니다. 그런 다음 정의되어 있고 하나 이상이 발견되면 두 번째 필드( $F[1]
) 및 를 인쇄합니다.$k
$k
hello
$k
두 번째 버전은 적어도 하나가 hello
항상 존재한다는 것을 알기 때문에 직접 인쇄할 필요가 없다는 점을 제외하면 동일합니다 .