다음과 같은 CSV 파일이 있습니다.
first_name,surname,email,
first_name2,surname2,email2,
....3,..
....4,...
각 열에는 동일한 수의 행이 있습니다.
각 열을 반복하고 각 열에서 값을 가져와서 명령으로 바꾸는 명령을 실행하고 싶습니다.
예를 들어,
for each_row;
do [command foo{first_name} .... bar{surname}.... sth_else{email}];
done
나는 다음과 같은 일을 할 생각입니다
for i in `awk -F, '{print $1}' my_file.csv`; do
some command with i`;
done
그러나 이렇게 하면 필드 1의 값으로만 명령을 실행할 수 있습니다. 각 반복에서 각 열의 값을 가져올 수 있도록 명령을 어떻게 실행합니까?
답변1
CSV가 "간단한 CSV" 형식이고 필드에 쉼표나 줄바꿈이 포함되어 있지 않다고 가정하면(일반 CSV 파일에서는 쉼표나 줄바꿈이 허용되고 필드는 올바르게 인용됩니다) 다음을 사용하여 필드를 직접 읽을 수 있습니다 read
.
while IFS=, read -r name familyname address; do
printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done <file.csv
유틸리티 read
는 각 행을 값이 있는 필드로 분할하고 $IFS
호출 시 변수에 쉼표가 포함되어 있는지 확인합니다 read
. 쉼표로 구분된 처음 두 개의 필드는 변수 로 name
끝나고familyname
나머지 줄결국 변수에 나타납니다 address
. 각 줄이 원치 않는 쉼표로 끝나는 경우(질문에서와 같이) 각 줄에서 더미 변수를 읽거나( 끝에 별도의 변수로 dummy
추가됨 ) 루프 내부의 with 값을 조정하여 후행 쉼표를 자릅니다.address
read
address
address=${address%,}
데이터의 백슬래시를 올바르게 읽으려면 -r
with를 사용합니다 .read
CSV 파일에 건너뛰어야 하는 헤더 행이 있는 경우
sed 1d file.csv |
while IFS=, read -r name familyname address; do
printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done
동일한 작업을 수행하는 대체 sed
명령(입력의 첫 번째 줄을 제거하고 다른 모든 줄을 전달)을 사용할 수 있습니다 .tail -n +2
답변2
내가 올바르게 이해했다면 xargs
다음과 같이 사용할 수 있습니다.
$ cat file | sed 's/,$//' | xargs -d, -I {} echo {} | sed 's/a/@/'
first_n@me
sur n@me
em@il
first_n@me2
sur n@me2
em@il2
sed 's/,$//'
마지막 쉼표를 제거합니다,
xargs -d, -I {}
-d,
: 매개변수 구분 기호로 쉼표를 사용하여 매개변수를 파이프 및-I {}
에 전달할 수 있습니다 .echo
sed
헤더 구문 분석 방지@그들의 답변을 확인하세요.
참고: 공백을 추가하여 입력을 약간 변경했습니다.
답변3
awk
다음과 같이 시스템 호출을 할 수 있습니다 .
awk -F',' '{system("<command> "$1" "$2" "$3)}' file
두 개의 공백으로 구분된 요소로 구성된 성처럼 쉘에 전달된 변수를 인용해야 할 수도 있습니다. 이는 또한 명령이 공백으로 구분된 항목을 이해하는 방법에 따라 달라집니다. 이 경우 다음을 사용하십시오.
awk -F',' '{system("<command> \""$1"\" \""$2"\" \""$3"\"")}'