다음 CSV 파일이 있습니다.
Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa
1000,"1 0 0 1",1002,1002,1003,1004,1005,"1 0 0 6",1007,1008,1009,1010,1011,1012,1013
100,101,102,102,103,104,105,"1 0 6 2",107,108,109,110,111,112,113
10001,10011,10021,10021,10031,10041,10051,10061,10071,10081,10091,10101,10111,10121,10131
.
.
.
.
내 목표는 bash 스크립트에서 CSV 매개변수(CSV의 모든 상태)와 해당 값을 설정하는 것입니다.
예를 들어
#!/bin/bash
Alabama=1000
.
.
.
Iowa=1013
따라서 내 bash 스크립트에서 각 매개변수를 읽을 수 있습니다.
예
echo $Alabama
1000
먼저 매개변수를 해당 값으로 설정하기 위해 다음과 같은 (잘못된) 코드를 작성해 보았습니다.
#!/bin/bash
counter=1
for CSV_COLUMN in Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois Indiana Iowa
do
export $CSV_COLUMN=` echo $CSV_LINE | cut -d',' -f$counter `
counter=$counter+1
done
테스트는 (bash 스크립트에서)
echo $Alabama
1000
내 아이디어를 구현하려면 코드를 어떻게 변경해야 합니까?
답변1
주문하다
awk -F, 'NR==1 { for (i=1; i<=NF; i++) sn[i]=$i }
NR==2 { for (i=1; i<=NF; i++) print sn[i] "=" $i; exit }' states
states
출력할 파일은 어디에 있습니까?
Alabama=1000
Alaska="1 0 0 1"
Arizona=1002
Arkansas=1002
California=1003
Colorado=1004
Connecticut=1005
Delaware="1 0 0 6"
Florida=1007
Georgia=1008
Hawaii=1009
Idaho=1010
Illinois=1011
Indiana=1012
Iowa=1013
-F,
awk
필드 구분 기호를 로 설정합니다,
.NR==1
"첫 번째 레코드(행)에서만 다음 작업을 수행하십시오"를 의미NR==2
합니다.- (첫 번째 항목)은
for
첫 번째 행의 각 필드를 반복하고 값(상태 이름)을 배열에 할당합니다sn
:sn[1]=Alabama
,sn[2]=Alaska
, ...). - 두 번째 루프는 두 번째 행의 각(쉼표로 구분된) 필드를 살펴보고 위에 표시된 대로
for
해당하는 주 이름(첫 번째 행의)과 쌍을 이룹니다 .=
- 그러면 파일의 나머지 부분을 읽을 필요가 없습니다
exit
.awk
그래서
평가$(awk -F, 'NR==1 { for (i=1; i<=NF; i++) sn[i]=$i } NR==2 { for (i=1; i<=NF; i++) print sn[i] "= $i;exit}' 상태)
이 출력은 캡처되어 일련의 명령으로 해석됩니다. 완벽한.
쉘 루프와 명령을 사용하기로 결정했다면 cut
다음을 고려하십시오.
values=$(sed -n '2p;2q' states)
counter=1
for state_name in $(sed 's/,/ /g;1q' states)
do
eval $state_name=$(echo "$values" | cut -d, -f$counter)
counter=$((counter+1))
done
또는 example/try()에서 했던 것처럼 상태 이름을 명시적으로 나열할 수 있습니다. 그런데 데이터가 이미 파일에 있는데 코드에서 데이터를 복사하는 이유는 무엇입니까? 변수를 제거하고 다음을 수행할 수 있습니다.for var in Alabama Alaska Arizona Arkansas …
values
eval $state_name=$(sed -n '2p;2q' states | cut -d, -f$counter)
하지만 이를 위해서는 states
파일을 한 번이 아닌 50번 읽어야 합니다. (또는 진술을 세어보면 2번이 아닌 51번이 됩니다 for state_name in $(sed 's/,/ /g;1q' states)
.)
답변2
다음 줄을 사용하세요.
read `sed -e 's/,/ /g' -e '1q;d' file` < <(sed -e 's/\ /\\\ /g' -e 's/"//g' -e 's/,/ /g' -e '2q;d' file)
설명하다:
첫 번째
sed
명령은 파일의 첫 번째 줄만 인쇄하고 쉼표(,
)를 공백으로 바꿉니다.Alabama Alaska Arizona Arkansas California ...
두 번째 sed 명령은 두 번째 줄에 대해 동일한 작업을 수행합니다(질문에서는 두 번째 줄의 값만 필요한 것 같습니다)
1000 1001 1002 1002 ...
.read -r
첫 번째 목록을 두 번째 목록에 할당합니다.
나중에 다음 명령을 사용하여 이러한 값을 테스트할 수 있습니다 echo
.
echo $Alabama
1000
echo $Alaska
1 0 0 1
echo $Georgia
1008