通过目录和所有嵌套文件中的模式获取文件列表,并迭代结果

通过目录和所有嵌套文件中的模式获取文件列表,并迭代结果

在一个目录“my_directory”中,其中有其他目录,具有多层嵌套,我想通过模式查找一些文件,然后将它们一一上传到远程服务器。在远程服务器上,它们应该复制到同一台服务器上相对于远程的路径 my_directory。为此,我将scp

我是从这个开始的:

ls -al my_directory | grep "*.my_custom."

尽管其中包含部分文件*.my_custom.存在,但它什么也没返回。

我怎么能够:

a) 通过某种模式找到这些文件

b) 在 bash 中循环枚举它们,这样我就可以将每个变量引用为变量?以便下一步将其上传到服务器。

答案1

您的方法存在两个问题:

  1. grep尽管grep需要正则表达式,但您在调用中使用了通配符(也称为“通配符”) 。这两个是不同的。在 glob 中,*表示“任意字符和任意长度的字符串”,而在正则表达式中,表示“零个或多个前面的字符”,*如果没有前面的字符,则表示文字。相反,.glob 中的 表示文字.,而在正则表达式中表示“任何单个字符”。因此,您grep将查找字面上包含星号的文件,然后查找任何单个字符,然后my_custom一遍又一遍地查找任何单个字符。对于您想要实现的匹配,正则表达式将是

    .*\.my_custom\.
    

    或者,因为你没有锚定它,所以简单地

    \.my_custom\.
    
  2. 您希望在 shell 脚本中使用生成的列表进行进一步处理。正如@Panki 已经注意到的,你应该从不解析的输出ls为此,它会偶然发现带有特殊字符的文件名。幸运的是,您可以返回到最初使用 glob 的尝试,并直接在 shell 中迭代文件:

    for file in *.my_custom.*
    do
      your_upload_command "$file"
    done
    

    请注意,shell 变量$file放在双引号中。这是为了确保不会发生不需要的分词,即您的 shell 脚本不会偶然发现文件名中的空格或任何其他特殊字符。

  3. 由于您声明要递归地执行此操作,因此可以通过对 shell 脚本进行较小的更改来实现这一点,方法是使用globstarshell 选项,自 Bash v4 起可用:

    shopt -s globstar
    for file in **/*.my_custom.*
    do
      your_upload_command "$file"
    done
    

答案2

这可以通过find.

find my_directory -name "*.my_custom." -type f -exec scp -i {} <username>@<host>:<path>/{}  \;

{}将包含从 my_directory 开始的匹配文件的路径。exec指定每场比赛要执行的命令。您可以修改您的scp路径,记住这两点。

答案3

我会这样做(在 GNU 系统上):

(cd my_directory && find . -name '*.my_custom.*' -type f -print0) |
  tar --null -T - -cf - | gzip -1 | ssh host 'cd my_directory && tar zxf -'

相关内容