awk
명령을 사용하려고합니다. div id = “1a680191bd”>
루프.
awk
로 자르고 싶은 일련의 문자열을 포함하는 변수가 있습니다. 데이터를 얻을 수 있습니다.
그 방법을 알고 있지만 정말로 원하는 것은 데이터를 연속적으로 자르는 것입니다.
그래서이 변수를 얻었습니다.
var="data1,data2,data3"
그리고 지금 현재 위치 :
for ((i=1; i<=3; i++)) do echo $(awk -F, "{print $1}" <<< $var) done
$1
루프에 의해 $i
성공하지 못했습니다.
댓글
답변
당신이 원하는 것을 달성 할 수 있습니다. awk 스크립트에서 큰 따옴표를 사용하여 쉘 변수를 삽입하려고합니다. 백 슬래시로 이스케이프하여 수행 할 수있는 리터럴 $
하나를 계속 유지하려고합니다. :
echo $(awk -F, "{print \$$i}" <<<$var)
이렇게하면 $i
가 1
로 확장됩니다. 각 반복에서 2
및 3
이므로 awk는 $1
, $2
및 $3
는 각 필드를 확장합니다.
또 다른 가능성은 쉘 변수를 -v
플래그를 사용하는 awk 변수 :
echo $(awk -F, -v i="$i" "{print $i}" <<<$var)
Awk 변수 i 를 동일한 이름의 셸 변수 내용에 할당합니다. awk의 변수는 필드에 사용되는 $
를 사용하지 않으므로 $i
는 i를 참조하기에 충분합니다. i 가 awk의 변수 인 경우 -번째 필드입니다.
-v
를 사용하여 awk 변수를 할당하는 것이 일반적으로 더 안전합니다. 접근 방식, 특히 임의의 문자 시퀀스를 포함 할 수있는 경우 내용이 의도에 반하는 awk 코드로 실행될 위험이 적습니다. 그러나 귀하의 경우에는 변수가 단일 정수를 보유하기 때문에 그다지 문제가되지 않습니다.
또 다른 옵션은 awk 자체에서 for
루프를 사용하는 것입니다. . 그 방법에 대한 자세한 내용은 awk 문서 (또는이 사이트 검색)를 참조하십시오.
댓글
- … 또는 입력 레코드 설정 구분자 적절하게
awk -v RS='[,\n]' 1 <<< "$var"
(또는 더 이식 가능하게printf "$var" | awk -v RS=, 1
) - @steeldriver awk 스크립트는 다음 위치에 세 필드를 모두 인쇄합니다. OP가 그냥 을 수행하고 있다는 점을 감안할 때 괜찮습니다. 셸 루프에서 다른 명령을 실행하는 데 관심이 있다는 가정하에 단일 필드를 추출하는 데 초점을 맞추 었습니다. 애초에 하나를 사용하게 된 동기가되었습니다 …)
- 이해했습니다. ' 그래서 OP에 대해 설명을해서 무엇을하는지 명확히했습니다. 정말 하고 싶습니다;)
- 첫 번째 는 주입 (및 보안 문제), 두 번째 o ne (
-v
사용)는 주사가 아닙니다. - 감사합니다. 귀하의 답변이 제 문제를 해결했습니다. 수년간 게시물을 읽은 후 처음으로 여기에 질문을 게시합니다. 실망하지 않았습니다. 정말 멋진 커뮤니티입니다!
답변
awk
를 사용하는 것 같습니다. 이 상황에서 과도합니다. tr
및 while-loop는 어떻습니까?
tr , "\n" <<<"$var" | while read; do echo $REPLY done
출력 :
data1 data2 data3
댓글
- 좋습니다.
REPLY
는read
기본 제공 셸 명령의 기본name
인수입니다. - 이렇게하려면 쉘이 기본 변수를 사용하여
read
에서 데이터를 입력해야합니다.bash
에서 , 그러나 이것은 표준이 아닙니다. 또한read
명령은 백 슬래시가 포함 된 경우 데이터를 수정할 수 있으며 값에서 측면 공백을 제거 할 수 있습니다. 또한 새 줄이 포함 된 값을 여러 값으로 읽습니다. 또한 쉘이 값을 분할하고 파일 이름 확장을 수행하지 못하도록하려면"$REPLY"
가 필요합니다.
답변
awk 는 수락 가능 j
(변수로) 및 $j
(필드 색인으로) :
for i in 1 2 3; do echo "$var" | awk -v j=$i -F , "{print $j}"; done
$i
“혼란 “예에서 awk
(셸 또는 자체 변수-우선 순위)는 $
접두사로 참조됩니다.
note
sh 셸은 다음을 지원하지 않습니다.
(( i=1; i<=3; i++; ))
및 <<< $var
구문
또한 for
에서 seq
명령을 사용할 수도 있습니다. div> 루프를 사용하여 숫자 시퀀스 생성을 더 세밀하게 제어 할 수 있습니다 (사용 가능한 경우).
설명
- 루프는 세 개의 파일이 호출 된 경우에만 작동합니다. ,
2
및3
. 또한 데이터에 파일 이름 패턴 (예 :*
)이 포함 된 경우 원하지 않는 결과를 초래할 수있는 셸에서 인용되지 않은 변수 확장을 사용합니다.echo
는 백 슬래시가 포함 된 경우 데이터를 추가로 수정할 수 있습니다.
Answer
#!/bin/sh var="data1,data2,data3" unset data while [ "$var" != "$data" ]; do data=${var%%,*} # delete first comma and the bit after it var=${var#*,} # delete bit up to first comma (and the comma) printf "data = "%s"\n" "$data" done
여기서는 변수 대체를 사용하여 var
변수의 값에서 쉼표로 구분 된 연속 데이터 필드를 각각 가져옵니다. 루프의 data
에 대한 첫 번째 할당은 첫 번째 쉼표 뒤의 $var
에서 모든 항목을 제거합니다. 그런 다음 var
변수가 수정되어 첫 번째 쉼표까지의 첫 번째 비트가 삭제됩니다.
"$var" = "$data"
는 문자열에 더 이상 수행 할 수 없음을 의미합니다.
이렇게하면 새 줄이 포함 된 쉼표로 구분 된 데이터 문자열을 처리 할 수 있습니다.
var="line1 line2,data2,last bit goes here"
var
의 위 값을 사용하면 위 스크립트가 출력됩니다.
data = "line1 line2" data = "data2" data = "last bit goes here"
삽입 된 줄 바꿈은 신경 쓰지 않습니다. 거의 awk
호출을 반복해야합니다.
awk
문자열을 쉼표로 구분 된 필드 집합으로 읽고 “다음 항목을 반복 할 수 있습니다.
printf "%s\n" "$var" | awk -F "," "{ for (i=1; i<=NF; i++) print $i }"
var="data1,data2,data3"
, 이것은 인쇄됩니다
data1 data2 data3
변수를 사용하여 $var
값을 비트로 분할하는 동시에 set -f
를 사용하여 파일 이름 확장을 비활성화합니다.
set -f oldIFS=$IFS; IFS="," set -- $var IFS=$oldIFS; unset oldIFS set +f for data do printf "data = "%s"\n" "$data" done
echo "${var//,/$'\n'}"
를 사용할 수 있습니다.)