공백이 있는 구분 기호를 기준으로 문자열을 자르는 방법

공백이 있는 구분 기호를 기준으로 문자열을 자르는 방법
variable_list="
 any:any:-a -b -c any
 one:one:-c -b -f -m mul
 mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
  c1=`echo $f | cut -d':' -f1`;
  c2=`echo $f | cut -d':' -f2`;
  c3=`echo $f | cut -d':' -f3-`;
  echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
  #exit 0; ###I made mistake here
done;

예상 출력:

c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul

편집 1:

나는 스크립트가 어리석었다는 것을 깨달았고 exit 0실제로 이와 같은 스크립트가 많기 때문에 첫 번째 반복에서는 첫 번째 줄만 테스트했습니다. 그것은 필요한 방식으로 작동합니다.

variable_list입력 형식/방식을 수정하지 않고 유지하여 위의 출력을 얻을 수 있습니까?

(저는 bash를 사용하고 있습니다)

답변1

문제는 데이터의 공백과 관련이 있습니다. 쉘은 문자열을 모든 공백의 단어로 분할하고 루프는 for단어를 반복합니다.

variable_list( 배열로 바꾸지 않는 솔루션은 이 답변의 마지막 부분을 참조하세요.)

대신 적절한 배열을 사용하세요.

variable_list=(
    "any:any:-a -b -c any"
    "one:one:-c -b -f -m mul"
    "mul:one:-c -b -f -m mul"
)

for var in "${variable_list[@]}"; do
    c1=$( cut -d':' -f1  <<<"$var" )
    c2=$( cut -d':' -f2  <<<"$var" )
    c3=$( cut -d':' -f3- <<<"$var" )
    printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done

배열을 사용하면 줄 바꿈이나 다른 문자를 사용하여 구분하지 않고도 각 개별 변수 집합을 자체 배열 항목으로 액세스할 수 있습니다.

코드는 또한 "here-strings"를 사용하여 (파이프 대신 ) bash문자열을 보냅니다 .cutecho

또는 더 효과적으로,

variable_list=(
    "any:any:-a -b -c any"
    "one:one:-c -b -f -m mul"
    "mul:one:-c -b -f -m mul"
)

for var in "${variable_list[@]}"; do
    IFS=':' read -r c1 c2 c3 <<<"$var"
    printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done

IFS콜론을 설정하면 입력이 콜론(공백, 탭 및 줄 바꿈 대신)으로 분할 read됩니다 .read

위의 인용문은 모두 중요합니다. 큰따옴표가 없으면 쉘은 의 값과 세 개의 변수에 대해 단어 분할 및 파일 이름 일치를 수행 variable_list합니다 var.c

관련된:


당신이 추구하는 것이 특정 출력뿐이라면 부정 행위를 할 수도 있습니다.

variable_list=(
    "any:any:-a -b -c any"
    "one:one:-c -b -f -m mul"
    "mul:one:-c -b -f -m mul"
)

( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%s\n' ${variable_list[@]} )

이는 설정 및 ( ) 셸 옵션이 스크립트의 나머지 부분에 영향을 미치지 않도록 printf하위 셸에서 실행됩니다 . 여기에 콜론을 설정하면 셸이 확장됩니다.IFS-fnoglobIFS인용되지 않음 variable_list배열은 세 개의 그룹으로 나뉘며, 각 그룹에는 세 개의 매개변수가 있습니다 printf. printf처음 세 개의 매개변수는 해당 형식 문자열에 따라 인쇄되며, 모든 매개변수가 처리될 때까지 형식은 세 개의 매개변수의 다음 집합에 재사용됩니다.

이렇게 하면 파일 이름 와일드카드 문자가 있는 경우 set -f인용되지 않은 확장자가 파일 이름 글로빙을 트리거하는 것을 방지할 수 있습니다 .variable_list


개행으로 구분된 문자열을 사용하십시오.

variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"

while IFS= read -r var; do
    IFS=':' read -r c1 c2 c3 <<<"$var"
    printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done <<<"$variable_list"

이는 마치 파일에서 온 것처럼 문자열에서 데이터를 읽습니다.

관련된:

답변2

awk를 사용하여 출력을 얻을 수 있습니다.

echo "$variable_list" | awk -F: '
{
  sub("^ ","")
  for(i=1;i<=NF;i++)
    sub(/^/,"c" i "==>",$i)
}1' OFS=" and "

관련 정보