for 루프 내부의 Awk 명령

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를 반복하는 것은 불필요 해 보입니다. (bash의 예에서는 매개 변수 대체 echo "${var//,/$'\n'}"를 사용할 수 있습니다.)
  • 실제로 변수에는 zenity 형식의 URL이 포함됩니다. 이 URL을 개별적으로 사용하고 싶기 때문에 각 URL을 개별적으로 가져와야합니다.
  • 관련성이 있지만이 경우에는 좋은 해결책이 아닙니다. 방법 AWK 명령에서 런타임에 값 할당

답변

당신이 원하는 것을 달성 할 수 있습니다. awk 스크립트에서 큰 따옴표를 사용하여 쉘 변수를 삽입하려고합니다. 백 슬래시로 이스케이프하여 수행 할 수있는 리터럴 $ 하나를 계속 유지하려고합니다. :

echo $(awk -F, "{print \$$i}" <<<$var) 

이렇게하면 $i1로 확장됩니다. 각 반복에서 23이므로 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 

댓글

  • 좋습니다. REPLYread 기본 제공 셸 명령의 기본 name 인수입니다.
  • 이렇게하려면 쉘이 기본 변수를 사용하여 read에서 데이터를 입력해야합니다. bash에서 , 그러나 이것은 표준이 아닙니다. 또한 read 명령은 백 슬래시가 포함 된 경우 데이터를 수정할 수 있으며 값에서 측면 공백을 제거 할 수 있습니다. 또한 새 줄이 포함 된 값을 여러 값으로 읽습니다. 또한 쉘이 값을 분할하고 파일 이름 확장을 수행하지 못하도록하려면 "$REPLY"가 필요합니다.

답변

는 수락 가능 j (변수로) 및 $j (필드 색인으로) :

 for i in 1 2 3; do echo "$var" | awk -v j=$i -F , "{print $j}"; done  

$i“혼란 “예에서 awk (셸 또는 자체 변수-우선 순위)는 $ 접두사로 참조됩니다.

note

셸은 다음을 지원하지 않습니다.

(( i=1; i<=3; i++; ))<<< $var 구문

또한 forseq 명령을 사용할 수도 있습니다. div> 루프를 사용하여 숫자 시퀀스 생성을 더 세밀하게 제어 할 수 있습니다 (사용 가능한 경우).

설명

  • 루프는 세 개의 파일이 호출 된 경우에만 작동합니다. , 23. 또한 데이터에 파일 이름 패턴 (예 : *)이 포함 된 경우 원하지 않는 결과를 초래할 수있는 셸에서 인용되지 않은 변수 확장을 사용합니다. 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 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다