编写对文件名列表进行操作的 bash 函数

编写对文件名列表进行操作的 bash 函数

我想cpfromserver在 bash 中定义该函数,以便当我运行时

$ 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.txt和从上的filename.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/

相关内容