Bash/awk를 사용하여 csv 파일의 첫 번째 열에 공백 채우기

Bash/awk를 사용하여 csv 파일의 첫 번째 열에 공백 채우기

일부 프로세스/계산을 자동화하려고 하는데 먼저 다소 어색한 형식을 지정해야 할 수도 있습니다.CSV파일 세트. (이를 위해 bash요청 시 사용합니다).

csv 파일 세트는 대략 다음 형식을 따릅니다.

CODE,Sitting,Jan,Feb,Mar,Apr,May,Jun,Jul,Totals
CLLK_J9,First Sitting,,,2,5,2,,,10
,Second Sitting,,,,,,,,1
RTHM_A8,First Sitting,,,1,,3,,,6
,Second Sitting,,,,,1,,,1
FFBJ_FA9,First Sitting,,,,8,6,,,25
,Second Sitting,,,,,11,,,12
UUYIOR_HJ9,First Sitting,,,1,3,6,,,17
IKRO_Lk8,First Sitting,,,,3,3,,,37
,Second Sitting,,,,6,11,,,34

여기에 이미지 설명을 입력하세요.

CODE이 열의 빈 필드를 이전 행의 필드 내용으로 채우려 고 합니다 . 일반적으로 이러한 빈 필드는 열 2의 "두 번째 앉아" 인스턴스 옆에 나타납니다. 따라서 위 예의 경우 결과는 다음과 같아야 합니다.

CODE,Sitting,Jan,Feb,Mar,Apr,May,Jun,Jul,Totals
CLLK_J9,First Sitting,,,2,5,2,,,10
CLLK_J9,Second Sitting,,,,,,,,1
etc.

awk이 작업에 상당히 강력한 유틸리티인 것 같아서 일부 문서를 읽기 시작했지만 아직 진전이 없었습니다. 아이디어?

답변1

밀러 사용(https://github.com/johnkerl/miller) 아주 간단해요. 달리기

mlr --csv fill-down -f CODE input.csv >output.csv

당신은 할 것

+------------+----------------+-----+-----+-----+-----+-----+-----+-----+--------+
| CODE       | Sitting        | Jan | Feb | Mar | Apr | May | Jun | Jul | Totals |
+------------+----------------+-----+-----+-----+-----+-----+-----+-----+--------+
| CLLK_J9    | First Sitting  | -   | -   | 2   | 5   | 2   | -   | -   | 10     |
| CLLK_J9    | Second Sitting | -   | -   | -   | -   | -   | -   | -   | 1      |
| RTHM_A8    | First Sitting  | -   | -   | 1   | -   | 3   | -   | -   | 6      |
| RTHM_A8    | Second Sitting | -   | -   | -   | -   | 1   | -   | -   | 1      |
| FFBJ_FA9   | First Sitting  | -   | -   | -   | 8   | 6   | -   | -   | 25     |
| FFBJ_FA9   | Second Sitting | -   | -   | -   | -   | 11  | -   | -   | 12     |
| UUYIOR_HJ9 | First Sitting  | -   | -   | 1   | 3   | 6   | -   | -   | 17     |
| IKRO_Lk8   | First Sitting  | -   | -   | -   | 3   | 3   | -   | -   | 37     |
| IKRO_Lk8   | Second Sitting | -   | -   | -   | 6   | 11  | -   | -   | 34     |
+------------+----------------+-----+-----+-----+-----+-----+-----+-----+--------+

답변2

시도해 보고 싶다면 awk다음과 같이 하면 됩니다.

awk -F',' -v OFS=',' 'FNR>1{if ($1!="") last=$1; else $1=last}1' input.csv

그러면 입력 및 출력 필드 구분 기호가 로 설정됩니다 ,.

그런 다음 각 행에 대해첫 번째 줄 이후( ), 첫 번째 열 ( )이 비어 있는지 FNR>1확인합니다 . 그렇지 않은 경우 값은 나중에 사용할 수 있도록 $1변수에 저장됩니다 . last비어 있으면 이전에 저장된 값으로 채워집니다.

1규칙 블록의 외부 지시문은 수정 사항을 포함하여 현재 줄을 { ... }인쇄합니다 . 이 명령(또는 실제로 평가되는 부울 조건)이 지정되거나 명시적인 /command가 규칙 블록 내에 제공되지 않는 한 현재 행은 인쇄되지 않습니다 awk.trueprintprintfawk

결과:

CODE,Sitting,Jan,Feb,Mar,Apr,May,Jun,Jul,Totals
CLLK_J9,First Sitting,,,2,5,2,,,10
CLLK_J9,Second Sitting,,,,,,,,1
RTHM_A8,First Sitting,,,1,,3,,,6
RTHM_A8,Second Sitting,,,,,1,,,1
FFBJ_FA9,First Sitting,,,,8,6,,,25
FFBJ_FA9,Second Sitting,,,,,11,,,12
UUYIOR_HJ9,First Sitting,,,1,3,6,,,17
IKRO_Lk8,First Sitting,,,,3,3,,,37
IKRO_Lk8,Second Sitting,,,,6,11,,,34

답변3

AWK 솔루션은 아니지만 ...

$ cat yourfile.csv | csv-sqlite 'select code, (select i2.code from input i2 where i2.code != "" and i2.rowid <= i1.rowid order by i2.rowid desc limit 1) as new_CODE, Sitting, Jan, Feb, Mar, Apr, May, Jun, Jul, Totals from input i1' -s
CODE         new_CODE     Sitting          Jan   Feb   Mar   Apr   May   Jun   Jul   Totals
CLLK_J9      CLLK_J9      First Sitting                2     5     2                 10
             CLLK_J9      Second Sitting                                             1
RTHM_A8      RTHM_A8      First Sitting                1           3                 6
             RTHM_A8      Second Sitting                           1                 1
FFBJ_FA9     FFBJ_FA9     First Sitting                      8     6                 25
             FFBJ_FA9     Second Sitting                           11                12
UUYIOR_HJ9   UUYIOR_HJ9   First Sitting                1     3     6                 17
IKRO_Lk8     IKRO_Lk8     First Sitting                      3     3                 37
             IKRO_Lk8     Second Sitting                     6     11                34

("-s"를 제거하면 CSV로 반환됩니다)

csv-sqlite의https://github.com/mslusarz/csv-nix-tools

쿼리가 도난당했습니다.이 답변.

답변4

모든 UNIX 시스템의 모든 쉘에서 awk를 사용하십시오.

$ awk 'BEGIN{FS=OFS=","} $1==""{$1=p} {p=$1} 1' file
CODE,Sitting,Jan,Feb,Mar,Apr,May,Jun,Jul,Totals
CLLK_J9,First Sitting,,,2,5,2,,,10
CLLK_J9,Second Sitting,,,,,,,,1
RTHM_A8,First Sitting,,,1,,3,,,6
RTHM_A8,Second Sitting,,,,,1,,,1
FFBJ_FA9,First Sitting,,,,8,6,,,25
FFBJ_FA9,Second Sitting,,,,,11,,,12
UUYIOR_HJ9,First Sitting,,,1,3,6,,,17
IKRO_Lk8,First Sitting,,,,3,3,,,37
IKRO_Lk8,Second Sitting,,,,6,11,,,34

관련 정보