bash 스크립트의 for 루프에 여러 변수를 매개 변수로 전달하는 방법은 무엇입니까? [폐쇄]

bash 스크립트의 for 루프에 여러 변수를 매개 변수로 전달하는 방법은 무엇입니까? [폐쇄]

저는 Linux를 처음 사용하고 bash 스크립트를 작성 중입니다. 스크립트에는 2개의 변수(내부에 변수 내용 포함)가 있습니다. 동일한 for 루프에서 이 두 변수를 전달하고 일부 작업을 수행하려고 합니다.

하지만 동일한 for 루프에서 2개의 변수를 전달하면 오류가 발생합니다. 아래 코드에서. 편의상 두 개의 매개변수를 전달하지만 실제로는 다릅니다. 명령에서 이러한 변수의 출력을 얻습니다.

아래는 내 코드입니다.

FILES="2019_06/
2019_07/"
FILESIZE="100
200"

for file in `cat $FILES`; for filesize in `cat $FILESIZE`
 do
 do
 if [ -n "$file" ] && if [ -n "$filesize" ] 
  then
echo  $file

   curl -i -XPOST "http://localhost:8086/write?db=S3check&precision=s" --data-binary 'ecmwftrack,bucketpath=ecmwf-archive/'$file' size=$filesize'

fi
 done
done

누구든지 for 루프에서 2개의 매개변수를 동시에 전달하도록 도와줄 수 있나요?

매개변수는 for 루프처럼 전달되어야 합니다.

FILES=2019_06 FILESIZE=100
FILES=2019_07 FILESIZE=200

다음은 오류 메시지입니다.

여기에 이미지 설명을 입력하세요.

도와주세요!

아래는 내 결과입니다

여기에 이미지 설명을 입력하세요.

아래는 내 곱슬 쿠만입니다

echo  curl -i -XPOST "http://localhost:xxxx/write?db=S3check&precision=s" --data-binary 'ecmwftrack,bucketpath=ecmwf-archive/'$files' size='$filesizes''


#!/bin/bash -x

# You said variables get their values from commands, so here 
# are stand-ins for those commands:
command_to_get_files(){
  aws s3 ls "s3://ui-dl-weather-ecmwf-ireland/ecmwf-archive/"| awk '{print $2}'  >>"$FILES"
}

command_to_get_filesizes(){
 for file in `cat $FILES`
 do
 if [ -n "$file" ]
  then
  # echo $file
   s3cmd du -r s3://ui-dl-weather-ecmwf-ireland/ecmwf-archive/$file | awk '{print $1}'>>"$FILESIZE"

 fi
 done
}

# I assume the values returned from the commands are whitespace delimited
# Therefore it is easy to use command substitution and transform the output
# of the commands into arrays:

files=( $(command_to_get_files) )

filesizes=( $(command_to_get_filesizes) )

답변1

이것이 내가 쓴 것입니다:

#!/bin/bash

while read file filesize; do
  if [[ -n "$file" && -n "$filesize" ]]; then
    # This printf is a stand-in for what your really want to do
    printf "FILES=%s FILESIZE=%s\n" "$file" "$filesize"
    # I commented out the curl invocation because I don't understand it
    #curl -i -XPOST "http://localhost:8086/write?db=S3check&precision=s" --data-binary "ecmwftrack,bucketpath=ecmwf-archive/$file" size="$filesize"
  fi
done <<'EOF'
2019_06 100
2019_07 200
EOF

마지막으로 구분된 문서에서 두 개의 변수를 읽습니다.

답변2

#!/bin/bash

# You said variables get their values from commands, so here 
# are stand-ins for those commands:

command_to_get_files(){
  echo "2019_06/
2019_07/"
}

command_to_get_filesizes(){
  echo "100
200"
}

# I assume the values returned from the commands are whitespace delimited
# Therefore it is easy to use command substitution and transform the output
# of the commands into arrays:

files=( $(command_to_get_files) )

filesizes=( $(command_to_get_filesizes) )

# Repeat this pattern for how ever many parameters you have

# Hat tip to Kamil for idea of using arrays and C-style for loop

for ((i=0; i<"${#files[@]}"; i++)) do
    # This printf is a stand-in for what your really want to do
    #printf "FILES=%s FILESIZE=%s\n" "${files[$i]%?}" "${filesizes[$i]}"
    echo curl -i -XPOST "http://localhost:8086/write?db=S3check&precision=s" --data-binary "ecmwftrack,bucketpath=ecmwf-archive/${files[$i]%?} size=${filesizes[$i]}"
done

퍼센트 물음표는 원하지 않는 것 같은 것을 %?제거합니다 ./

라는 파일에 넣고 myscript.sh실행하십시오.

$ chmod +x myscript.sh
$ ./myscript.sh 
FILES=2019_06 FILESIZE=100
FILES=2019_07 FILESIZE=200

업데이트: 출력이 printf다음으로 대체됩니다 echo curl ....

$ ./myscript.sh 
curl -i -XPOST http://localhost:8086/write?db=S3check&precision=s --data-binary ecmwftrack,bucketpath=ecmwf-archive/2019_06 size=100
curl -i -XPOST http://localhost:8086/write?db=S3check&precision=s --data-binary ecmwftrack,bucketpath=ecmwf-archive/2019_07 size=200

답변3

하나의 변수에 여러 값을 넣고 따옴표 없이 사용하고 토큰화에 의존하여 값을 다시 분리하는 것은 좋은 습관이 아닙니다. 배열을 사용하세요. 동일한 인덱스를 사용하여 두 개 이상의 배열에서 "병렬로" 값을 검색할 수 있습니다. 이렇게 하면 문제가 해결됩니다.

동일한 크기의 배열 두 개를 준비하고 다음과 같이 반복합니다.

#!/bin/bash

file=( "2019_06/" "2019_07/" )
filesize=( "100" "200" )

for ((i=0; i<"${#file[@]}"; i++)) do
   echo "${file[i]}" "size=${filesize[i]}"
done

echo …원하는(및 조정된) 블록으로 교체합니다 if … curl ….


및가 스크립트가 데이터를 수신하는 변수이고 이를 변경할 수 없으며 토큰화에 의존해야 하는 FILES경우 FILESIZE변수에서 배열을 만듭니다.

file=( $FILES )
filesize=( $FILESIZE )

변수는 참조되지 않으며 분사(및파일 이름 생성) 이 단계에서 발생합니다.

답변4

S3 작업을 병렬로 수행하려는 경우가 종종 있습니다.

FILES="2019_06/
2019_07/"
FILESIZE="100
200"

doit() {
   s3cmd du -r s3://ui-dl-weather-ecmwf-ireland/ecmwf-archive/"$1" |
     awk '{print $1}'>>"$2"
}
export -f doit

parallel doit {1} {2} ::: $FILES :::+ $FILESISZE

관련 정보