![공백이 있는 구분 기호를 기준으로 문자열을 자르는 방법](https://linux55.com/image/136808/%EA%B3%B5%EB%B0%B1%EC%9D%B4%20%EC%9E%88%EB%8A%94%20%EA%B5%AC%EB%B6%84%20%EA%B8%B0%ED%98%B8%EB%A5%BC%20%EA%B8%B0%EC%A4%80%EC%9C%BC%EB%A1%9C%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%20%EC%9E%90%EB%A5%B4%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
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
문자열을 보냅니다 .cut
echo
또는 더 효과적으로,
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
-f
noglob
IFS
인용되지 않음 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 "