결과

결과

일부 데이터를 작업으로 변환해야 합니다. 나는 이것이 awk의 매우 간단한 작업처럼 보일 것이라고 확신하지만 나는 그것이 매우 불편합니다.

각 데이터 요소(및 열)는 탭으로 구분됩니다. 데이터 요소에는 공백과 특수 문자가 포함될 수 있지만 탭은 포함될 수 없습니다.

입력 예:

column1 column2 column3
rowA1   rowA2   rowA3
rowB1   rowB2   rowB3

예상 출력:

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

(몇 줄이든 몇 백 줄을 넘지 않음)

이 작업을 수행하는 방법에 대한 단서가 있습니까? (Linux에서는 awk 또는 표준 명령줄 도구를 사용하세요)

답변1

예를 들어:

{
    if (NR==1){
        for (i=1; i<=NF; ++i){
            arr[i] = $i
        }
    }else{
        for (i=1; i<=NF; ++i){
            print(arr[i]," = ",$i)
        }
    }
    print("")
}

달리기:

awk -f script.awk input

답변2

cat data |
while IFS=$'\t' read -r -a a; do
   case ${flag+'set'} in
      "set" )
         set -- "${a[@]}"
         for c in "${C[@]}"; do echo "$c = $1"; shift; done
         echo ;;

      * ) C=( "${a[@]}" ); flag= ;;
   esac
done

sed -Ee '
   1h;1N
   /^\n$/{
      $d;P;g;N
   }
   s/^(\S+)\s*((\S.*)?)\n(\S+)\s*((\S.*)?)/\1 = \4\n\2\n\5/
   P;D
' data

perl -F'\t+' -lane '
   @C or @C = @F,next;
   print "$C[$_] = $F[$_]" for 0 .. $#C;
   eof or print q[];
' data

결과

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

설명하다

  1. bash

    C*) 플래그가 설정되지 않은 동안 배열의 첫 번째 행을 저장합니다. 그런 다음 다음에 여기까지 오지 않도록 빨리 설정하세요. *) 명령을 사용하여 a배열을 매개변수로 분할합니다 set. *) 그런 다음 루프에서 "${c[@]}"를 통해 액세스하고 for$1로 인쇄(그런 다음 이동)하는 열을 반복합니다. *) IFS는 구성에 따라 탭으로 설정됩니다 $'\t'. 특수 문자 중 하나이므로 일련의 문자가 하나로 축소되므로 빈 필드가 표시되지 않습니다.

  2. perl

    *) FS를 하나 이상의 TAB:으로 설정하고 -F'\t+'자동 분할 모드를 켭니다. *) 배열 bash의 첫 번째 행에 있는 열 데이터를 저장하는 솔루션 기반의 논리와 동일합니다 . @C배열 @C및 현재 레코드 필드 데이터를 @F각각 하나씩 인쇄합니다.

  3. sed

    *) 여기서는 먼저 모든 탭 문자를 공백으로 변환합니다. *) 첫 번째 행과 열 데이터를 예약된 공간에 저장합니다. *) 다른 모든 행의 경우 열을 현재 행에 추가합니다. *) 그런 다음 현재 행/열에서 첫 번째 요소를 선택하고 이러한 인쇄된 내용을 제거하여 패턴 공간을 줄입니다. *) 남은 공간이 없을 때 정지 상태가 발생합니다.

관련 정보