표준 입력의 데이터를 개행 문자로 구분된 인수로 받는 스크립트가 있습니다.
string1,string2
string3,string4
string1,string2
와 별도로 가져가고 싶습니다 string3,string4
. 그러나 알 수 없는 수의 그러한 줄을 받았고 내 스크립트는 처음 두 줄만 읽은 다음 중지합니다. 표준 입력에서 구문 분석을 시도했지만 \n
작동하지 않습니다. 이 문제를 어떻게 처리해야 합니까?
나는 이렇게 읽으려고 노력한다
for i in "$@"
do
var1=$(echo "$i" | cut -f2 -d,)
var2=$(echo "$i" | cut-f2 -d,)
#etc
input.txt
내가 실제로 달성하고 싶은 것은 다음 유형의 입력이 포함된 파일이 있다고 가정하는 것입니다 .
string1,string2
string3,string4
이렇게 하면 문자열의 줄 수에 관계없이 각 줄을 가져와서 두 변수에서 개별적으로 추출하고 cat input.txt | ./myscript.sh
싶습니다 .stringI,stringJ
답변1
텍스트 처리를 수행하려는 경우 가장 확실한 방법은 awk
이를 위해 특별히 설계된 것을 사용하는 것입니다(또는 사용할 수도 있음 perl
).sed
awk -F, '{print "something with "$1" and "$2}'
입력이 실제 CSV인 경우 다음과 같이 더 복잡한 값을 가질 수 있습니다.
"field, with comma" , "and with
newline", "or ""quotes"""
전용 csv 구문 분석 유틸리티를 사용 perl
하고 싶을 수도 있습니다 .python
예를 들어 이러한 필드를 인수로 사용하여 일부 특정 명령을 실행해야 하기 때문에 이러한 필드를 셸 변수로 제공해야 하는 경우 다음을 수행해야 합니다.
while IFS=, read -r a b rest; do
something-with "$a" "$b"
done
GNU parallel
병렬 실행도 참조하세요:
PARALLEL_SHELL=sh parallel -C, 'something-with {1} {2}'
그러나 GNU는 parallel
상당한 오버헤드를 발생시키므로 병렬화는 그만한 가치가 있어야 합니다.
쉘은 ksh93
실제로 CSV 형식을 이해합니다(위의 복잡한 예와 같이 개별 필드에 대한 참조를 처리함).
while IFS=, read -rS a b rest; do
do-something-with "$a" "$b"
done
답변2
여러 줄의 사용자 입력을 얻으려면 -d 옵션과 함께 read를 사용할 것을 제안합니다.
또는 tr '\n' ' '
새 줄을 공백으로 변환하는 방법을 사용합니다. 이는 상당히 해키적입니다.
나는 방법을 모르지만 tr을 사용하여 EOF를 새 줄로 변환하면 예상한 대로 완벽하게 수행될 수 있습니다.
좀 더 구체적인 정보가 필요하시면 댓글 남겨주세요.
답변3
(어떤 이유로) 모든 입력 라인을 배열에 넣으려면 bash에서 다음을 사용할 수 있습니다.
readarray -t input_lines
그런 다음 각 행은 인덱스 배열의 요소로 저장됩니다 input_lines
. -t
각 줄에서 개행 문자를 제거하는 것입니다 .