해당 첫 번째 행의 내용을 기반으로 열 찾기

해당 첫 번째 행의 내용을 기반으로 열 찾기

TSV그래서 다음과 같은 파일이 있습니다 .

Hello world how are you
1 2 3 4 5
6 7 8 9 0

(위의 손글씨 장난감 예시에서는 각 줄의 모든 내용을 공백으로 구분했습니다.)

내 목표는 "how"와 "are"가 포함된 열을 첫 번째 행 값으로 가져오는 것입니다. 따라서 출력은 다음과 같습니다.

how are
3 4
8 9

문제는 이러한 패턴(예: "어떻게" 및 "is")이 어느 열에 나타날지 알 수 없다는 것입니다. 예를 들어 TSV파일은 실제로 다음과 같이 배열될 수 있습니다.

Hello how world are you
1 3 2 4 5
6 8 7 9 0

예를 들어, 나는 이것을 처리하는 방법을 알고 있지만 python(파일을 바꾸고 원하는 줄을 선택하기만 하면 됩니다), 쉘에서 이 작업을 수행하고 싶습니다(이유로 인해). 문제는 어떻게 해야할지 모르겠다는 것입니다. 명령줄 유틸리티를 사용하여 전치도 가능하다는 것을 알고 있습니다(예를 참조하세요).여기) 하지만 가능하다면 그렇게 큰 코드는 피하고 싶습니다. 나의 초기의 단순한 해결책은 단지 grep"어떻게"와 "is"였지만 그것은 분명히 전체 파일을 반환하므로 계속해서 막히게 됩니다.

어떤 도움이나 조언이라도 대단히 감사하겠습니다!

편집: 이 컴퓨터에 새 도구를 설치할 권한이 없다는 점을 언급해야 합니다. 나는 또한 그것이 실제로 무엇을 제공하는지 확신하지 못합니다. 도움이 된다면 이것은 입니다 Scientific Linux 7.3 (Nitrogen).

답변1

사용 csvtool1:

csvtool -t ' ' -u ' ' namedcol how,are file

-t Input separator char.
-u Output separator char.

 namedcol <names>
    Assuming the first row of the CSV file is a list of column headings,
    this returned the column(s) with the named headings.

^sudo apt install csvtool

답변2

awk첫 번째 줄에 일치하는 키워드가 있는지 확인하고 열 번호를 기록한 다음 해당 값을 인쇄할 수 있습니다 .

#first line -> Select columns based on keyword
NR==1 {
  for (i = 1; i <= NF; i++) {
    if ( $i == "how" ) {col_how=i}
    if ( $i == "are" ) {col_are=i}
  }
}
#print selected columns including header line
NR>=1 {
  print $col_how, $col_are
}

예를 들어 저장 script.awk하고 실행하십시오.

awk -f script.awk datafile

편집하다:

조옮김 및 ing 아이디어 grep도 쉽게 구현할 수 있습니다.

datamash transpose <datafile | grep 'how\|are' | datamash transpose

-t ' '공백을 구분 기호로 정의하는 데 사용됩니다 . 그러나 매우 긴 파일의 경우 RAM 제한이 발생할 수 있습니다. 그러나 대부분의 시스템에는 표준으로 설치되지 않을 수 있습니다.

답변3

$ cat tst.awk
BEGIN {
    cols = (cols == "" ? "how are" : cols)
    nf = split(cols,tgts)
    FS = OFS = "\t"
}
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
}
{
    for (i=1; i<=nf; i++) {
        printf "%s%s", $(f[tgts[i]]), (i<nf ? OFS : ORS)
    }
}

.

$ awk -f tst.awk file
how     are
3       4
8       9

.

$ awk -v cols='are world you Hello' -f tst.awk file
are     world   you     Hello
4       2       5       1
9       7       0       6

관련 정보