
다음과 같은 파일이 있습니다.
Time Flag
0.65 5.885581e-01
0.56 5.847484e-01
0.58 5.278409e-01
0.57 1.140746e+00
1.00 0
0.00 0
1.00 1
0.00 0
하지만 그것은 내가 글을 쓸 때 무언가를 바꾸는 것을 잊어버렸기 때문입니다. 따라서 타이밍의 절반은 플래그 열에서 끝나고 플래그의 절반은 시간 열에서 끝납니다. 그랬어야 했어
Time Flag
0.65 1
0.59 0
0.56 0
0.58 0
0.58 1
0.53 1
0.57 0
1.14 0
따라서 이 작은 예에서는 처음 4개 행이 첫 번째 열이 되어야 합니다. 마지막 4개 행은 두 번째 열이 되어야 합니다. 각 열의 요소 중 절반은 원본 파일에서 올바른 형식(교대 방식)으로 지정되어 있습니다. 모양을 바꾸고 형식을 바꾸는 가장 쉬운 방법은 무엇입니까?
답변1
$ awk 'NR > 1 { d[++n] = $1; d[++n] = $2 } END { print "Time", "Flag"; for (i = 1; 2*i <= n; ++i) printf "%.2f%s%d%s", d[i], OFS, d[n/2 + i], ORS }' file
Time Flag
0.65 1
0.59 0
0.56 0
0.58 0
0.58 1
0.53 1
0.57 0
1.14 0
이 awk
코드는 모든 데이터를 행 단위로 읽어 배열의 연속 요소로 읽습니다 d
(헤더 건너뛰기).
END
블록 에서 헤더가 인쇄된 다음 i
1에서 배열 길이의 절반까지 반복하여 d
인덱스(시간 값)의 값 과 마크 (플래그 값) i
의 값을 인쇄합니다. n/2 + i
시간 값이 소수점 이하 두 자리의 부동 소수점 값으로 인쇄되고 플래그 값이 정수로 인쇄되도록 출력 형식을 완료합니다.
OFS
변수는 ORS
기본 출력 필드와 레코드 구분 기호를 보유합니다(기본값은 공백과 줄 바꿈). 탭으로 구분된 출력의 경우 awk -v OFS='\t' '{ ... }' file
.
참고로 이 awk
코드는 독립형 스크립트로 작동합니다.
#!/usr/bin/awk -f
NR > 1 {
d[++n] = $1
d[++n] = $2
}
END {
print "Time", "Flag"
for (i = 1; 2*i <= n; ++i)
printf "%.2f%s%d%s", d[i], OFS, d[n/2 + i], ORS
}
답변2
OP에는 문제가 파일을 반으로 분할하고 각 반을 복구한 다음 다시 결합해야 한다고 명시되어 있지 않지만 해당 지식 없이 이를 수행하는 방법을 알고 싶습니다.
나는 정말 좋아한다csvkit특히GoCSV선언적 파이프라인 처리용.
변환/설정
첫 번째 단계는 고정 너비 샘플 데이터를 CSV로 변환하는 것입니다. csvkit을 사용하면 열 너비 패턴을 지정할 수 있습니다...
스키마.csv
column,start,length
Time,0,4
Flag,7,13
그런 다음 CSV로 변환합니다.
in2csv -s schema.csv input.txt > input.csv
분리 및 전치
입력을 플래그와 시간이라는 범주별로 나누고 싶습니다. 그런 다음 각 범주에 대해 단일 행 CSV 집합을 만듭니다(다음 단계의 전치를 위해).
gocsv filter -c 2 --regex "^[01]$" input.csv |
gocsv split --max-rows 1 --filename-base flags
보완적인 시간에는 동일한 패턴이 사용됩니다 --exclude
.
gocsv filter -c 2 --regex "^[01]$" --exclude input.csv |
gocsv split --max-rows 1 --filename-base times
그러면 다음과 같은 파일 세트가 생성됩니다.
ls flags-*.csv
flags-1.csv flags-2.csv flags-3.csv flags-4.csv
각각은 다음과 같습니다.
로고-1.csv
Time,Flag
1.00,0
또는:
times-4.csv
Time,Flag
0.57,1.140746e+00
헤더는 Time,Flag
그다지 중요한 것은 아니지만, 헤더가 존재하고 전치된 구조에 영향을 미치는지 보는 것이 중요합니다.
각 파일에 대해 전치를 반복하고 두 번째 열을 선택하고(잘못된 헤더가 첫 번째 열이 되기 때문에) 적절한 헤더로 마무리합니다.
for FILE in flags-*; do
gocsv transpose $FILE |
gocsv select -c 2 |
gocsv cap --names Flag \
> trans_$FILE;
done
for FILE in times-*; do
gocsv transpose $FILE |
gocsv select -c 2 |
gocsv cap --names Time \
> trans_$FILE;
done
기둥으로 쌓인
플래그와 시간을 자체 열에 쌓습니다.
gocsv stack trans_flags* > col_flag.csv
gocsv stack trans_times* > col_time.csv
그런 다음 함께 압축합니다(저는 그냥 사용하겠습니다).csvlook더 예쁜 Markdown 테이블이 있지만 숫자도 정규화하기 때문입니다! ):
gocsv zip col_time.csv col_flag.csv > output.csv
csvlook output.csv
시간 | 배너 |
---|---|
0.650… | 1 |
0.589… | 0 |
0.560… | 0 |
0.585… | 0 |
0.580… | 1 |
0.528… | 1 |
0.570… | 0 |
1.141… | 0 |
이것은 귀엽다.
그러나 마지막 단계는 GoCSV에 내장된(나에게 새로운) SPRIG 템플릿과 round
함수를 사용하여 부동 소수점, 정수 및 과학적 표기법을 정리하는 것입니다. 원래 열을 기반으로 새 열을 추가한 다음 새 열이나 서식이 지정된 열만 선택합니다.
cat output.csv |
gocsv add -n Time -t "{{round .Time 2}}" |
gocsv add -n Flag -t "{{round .Flag 0}}" |
gocsv select -c 3- |
gocsv tsv
우리는 다음을 얻었습니다:
Time Flag
0.65 1
0.59 0
0.56 0
0.58 0
0.58 1
0.53 1
0.57 0
1.14 0