파일 이름 목록에 대해 작동하는 bash 함수 작성

파일 이름 목록에 대해 작동하는 bash 함수 작성

bash에서 이 함수를 정의 하여 cpfromserver실행할 때

$ cpfromserver xxx yyy zzz

제가 입력한 것과 결과가 같습니다

$ scp [email protected]:"/some/location/xxx/xxx.txt /some/location/xxx/xxx.pdf /some/location/yyy/yyy.txt /some/location/yyy/yyy.pdf /some/location/zzz/zzz.txt /some/location/zzz/zzz.pdf" /somewhere/else/

이는 다양한 매개변수와 함께 작동합니다.

(즉, 함수 매개변수로 지정한 각 함수에 대해 함수는 디렉터리를 로컬 디렉터리로 복사해야 하며 filename.txtfilename.pdf모든 작업을 단일 연결로 수행해야 합니다.)/some/location/filename/remote.server/somewhere/else/filenamessh

현재 단일 매개변수에 대해 작동하는 함수를 작성하고 이를 반복하지만 이는 ssh각 매개변수에 대해 별도의 연결을 생성하므로 바람직하지 않습니다.

내 어려움은 함수 매개변수를 위치( , 등)별로 개별적으로 작업하는 방법만 알지만 전체 목록에서 작업하는 방법은 모른다는 $1것 입니다.$2

[나는 이 함수를 나만의 편의 도구로 작성했기 때문에 따옴표나 줄 바꿈 등이 있는 파일 이름과 같은 병리적인 경우를 처리하는 것보다 이해하기 쉬운 것을 우선시합니다. 나는 내가 사용할 파일 이름이 잘 작동할 것임을 알고 있습니다. ]

답변1

다음 방법을 시도해 보세요.

cpfromserver () {
    files=''
    for x in "$@"
    do
        files="$files /some/location/$x/$x.txt /some/location/$x/$x.pdf"
    done
    scp [email protected]:"$files" /somewhere/else/
}

댓글의 중요한 경고: "복잡한 파일 이름에는 이 솔루션이 확실히 작동하지 않는다는 점은 주목할 가치가 있습니다. 파일 이름에 공백, 개행 또는 따옴표가 포함되어 있으면 이 접근 방식은 확실히 실패합니다."

답변2

간단한 예는 다음과 같습니다.

#!/bin/bash

files_to_copy=''
destination_directory=''

while (("$#")) ; do
  if [[ "$@" = "$1" ]] ; then
    # last argument
    destination_directory="$1"
  else
    # argument
    files_to_copy="$files_to_copy $1"
  fi
  shift
done

scp [email protected]:"$files_to_copy" $destination_directory;

실행하면 다음을 ./example.sh foo.pdf foo.txt foo.jpg backup/얻을 수 있습니다.

# this will be executed
scp [email protected]:" foo.pdf foo.txt foo.jpg" backup/

답변3

주요 아이디어는 (루핑을 통해서도) 작업할 파일 목록이 포함된 문자열을 준비한 다음 해당 문자열을 명령에 파이프하는 것입니다.

sloc='/some/location'
unset flist
for i in "$@"
do
    flist[${#flist[*]}]="$sloc/$i/$i".pdf
    flist[${#flist[*]}]="$sloc/$i/$i".txt
done
scp [email protected]:"${flist[@]}" /somewhere/else/

관련 정보