![결과](https://linux55.com/image/10040/%EA%B2%B0%EA%B3%BC.png)
일부 데이터를 작업으로 변환해야 합니다. 나는 이것이 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
설명하다
bash
C
*) 플래그가 설정되지 않은 동안 배열의 첫 번째 행을 저장합니다. 그런 다음 다음에 여기까지 오지 않도록 빨리 설정하세요. *) 명령을 사용하여a
배열을 매개변수로 분할합니다set
. *) 그런 다음 루프에서 "${c[@]}"를 통해 액세스하고for
$1로 인쇄(그런 다음 이동)하는 열을 반복합니다. *) IFS는 구성에 따라 탭으로 설정됩니다$'\t'
. 특수 문자 중 하나이므로 일련의 문자가 하나로 축소되므로 빈 필드가 표시되지 않습니다.perl
*) FS를 하나 이상의 TAB:으로 설정하고
-F'\t+'
자동 분할 모드를 켭니다. *) 배열bash
의 첫 번째 행에 있는 열 데이터를 저장하는 솔루션 기반의 논리와 동일합니다 .@C
배열@C
및 현재 레코드 필드 데이터를@F
각각 하나씩 인쇄합니다.sed
*) 여기서는 먼저 모든 탭 문자를 공백으로 변환합니다. *) 첫 번째 행과 열 데이터를 예약된 공간에 저장합니다. *) 다른 모든 행의 경우 열을 현재 행에 추가합니다. *) 그런 다음 현재 행/열에서 첫 번째 요소를 선택하고 이러한 인쇄된 내용을 제거하여 패턴 공간을 줄입니다. *) 남은 공간이 없을 때 정지 상태가 발생합니다.