배열을 구성하여 이 형식으로 파일에 쓰려고 합니다. 즉, 파일 내용은 다음과 같아야 합니다.
hero_pairscore=( askdjfh sdf,sdlkfj lksf,dfgdf,dsflkgj,asdlkf ....)
여기서 요소는 으로 구분됩니다 comma
. 이를 위해 다음 코드를 작성했습니다.
#!/bin/bash
#set -x
hero_pairscore=()
while read line
do
$( IFS=",";hero_pairscore+=( "$line" )
done < true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
하지만 생성된 파일에는 이 내용만 포함되어 있습니다 hero_pairscore=( )
. 내 코드에 어떤 문제가 있으며 원하는 출력을 제공하려면 어떻게 수정해야 합니까?
답변1
여기서 해야 할 일은 다음과 같습니다.
변수를 설정합니다. 우리는 이것을 사용할 것입니다:
var="kijhg, fbjhku,,,ioy fbjfr, kjmyhg"
파일 이름 확장 설정
$IFS
및 방지:IFS=, ; set -f
set
출력할 쉘 배열$@
.set -- $var
상위 셸
$IFS
및 셸 매개변수를 재설정합니다.unset IFS ; set +f
오랫동안 살다! 여러 반복과 공백 등도 보존합니다!
printf %s\\n "$@"
산출
kijhg fbjhku ioy fbjfr kjmyhg
어쨌든 내 말을 들어주세요. a가 아닌 모든 문자는 ,
유지됩니다.
전환하다
특히 bash 배열 대신 실제 쉘 배열을 사용하는 것이 좋습니다. 왜냐하면 즉시 스플리터로 변환할 수 있기 때문입니다.
printf %s "$*"
#OUTPUT#
kijhg fbjhku ioy fbjfr kjmyhg %
IFS=, ; printf %s "$*"
#OUTPUT#
kijhg, fbjhku,,,ioy fbjfr, kjmyhg
$*
첫 번째 문자에서 셸의 위치 인수 배열을 분할하는 특별한 POSIX 지정 품질로 인해 $IFS
많은 양의 데이터를 쉽게 변환할 수 있습니다. "quote"
매개변수 배열을 보호하면서도 원하는 단일 문자로 분할 할 수 있습니다 . 처음에 제대로만 하면 됩니다.
추가/접두사
POSIX는 또한 이에 대한 특별한 속성을 지정합니다 "$@"
. "$1"... eval "\${$#}"
각 인수의 주소 지정 형식 외에도 인수 "$@"
(인용된 경우) set
는 의 현재 값에 관계없이 마지막 인수이므로 모든 셸 인수로 안전하게 확장할 수 있습니다. $IFS.
따라서 배열의 시작 부분에 목록을 추가하려면 다음을 수행할 수 있습니다.
set -- $list "$@"
머리/꼬리 방향:
set -- $head "$@" $tail
배열을 3배로 늘리려면:
set -- "$@" "$@" "$@"
현재 합계
데이터 흐름이 매우 크지 않은 한 다음 작업은 현재 작업보다 약간 더 빠를 수 있습니다.(그러나 파일 작업을 하는 경우 쉘 분할을 완전히 피하는 것이 가장 좋습니다):
( set -f -- ; IFS=, ; while read -r line ; do set -- "$@" $line ; done
printf %s "$*" ) | cat >out
어쩌면 TR?
하지만 내가 이해하지 못하는 것은 – 당신은 무엇을 하고 있나요? 개행 문자를 쉼표로 바꾸시겠습니까? 내 말은 -데이터가 이미 개행 문자 외에 쉼표로 구분되어 있습니까?만일이 경우라면:
tr '\n' ',' <in >out
답변2
내가 해야 할 일을 해라생각하다당신이 하려는 일은 쉼표로 구분된 각 필드를 true_pairscore.txt
배열 변수로 읽는 것입니다. 코드에는 큰 문제가 없습니다. 해당 줄 $(
의 시작 부분이 IFS
분명히 잘못되어 스크립트에 오류가 발생하게 됩니다(아마도 이것이 출력이 없는 이유일 것입니다). 그 외에 코드의 주요 수정 사항은 단어 분할을 $line
원하기 때문에 주변 따옴표를 제거하는 것입니다 (일반적으로 이를 방지하기 위해 사용합니다).bash
IFS
#!/bin/bash
set -o noglob
OIFS=$IFS
IFS=","
hero_pairscore=()
while IFS= read -r line
do
hero_pairscore+=( $line )
done < true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
set +o noglob
IFS=$OIFS
그러나 위의 작업을 단 두 줄로 수행하는 방법은 다음과 같습니다.
IFS=$',\n' read -ra hero_pairscore -d '' <true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
고쳐 쓰다
embed.txt
다른 쉘에서 파일을 가져오려면 배열 에 기록된 각 요소를 bash
인용해야 할 수도 있습니다 . hero_pairscore
이렇게 하려면 echo "hero_pairscore=( ${hero_pairscore[@]} )"
다음으로 바꾸세요.
echo "hero_pairscore=( $(printf '"%s" ' "${hero_pairscore[@]}") )"