什么适合识别可变长度文件名的正则表达式?

什么适合识别可变长度文件名的正则表达式?

I have a bash script that classifies and retrieves files from a remote server. I have trouble with the classification step, which is based on the file names.

I am correctly able to identify the different families of files that are defined by the start of the filenames. Filenames can be:

ala-olo_ulu-1602915797.txt
ala-olo_ulu-1602915799.txt
ili-olo-1602915897.txt
ili-olo-1602915997.txt
ili-olo-pip-1602925797.txt
ili-olo-pip-1602935797.txt

In this example, I have 3 families: ala-olo_ulu ili-olo ili-olo-pip (pure examples :))

Each family is treated in one iteration of a loop. In such an iteration, I have the family name available in an variable BASE_NAME (for instance ili-olo).

My trouble is the taring step, before rsync'ing the files to local. I am managing it with the following ssh command.

      ssh root@"${RMT_IP}" '
          for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do
            tar -rf "'${BASE_NAME}'.tar" ${FILE} --remove-files
          done' < /dev/null

不幸的是,使用此脚本,如果ili-olo在之前进行管理ili-olo-pip,那么存档将包含两个系列(它们都共享相同的开始)。当ili-olo-pip被管理时,它们将不再是任何文件,并且 tar 命令以错误结束。 (这就是我发现问题的方法)。

我想,我应该使用正则表达式来指定文件名的可变部分是数字部分。请问,如何更改for循环定义,以便以相同字符串开头的系列不会进入相同的 tar?

for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do

例如,数字部分始终具有相同的位数(它是时间戳,具有秒精度)1602915797

我感谢你的帮助。祝你有美好的一天,贝斯特,皮埃尔

答案1

如果您可以zsh同时用作本地和远程 shell,那就更容易了:

ssh root@$RMT_IP zsh << EOF
  set -o extendedglob # for (#c10)

  for file in ${(qq)BASE_NAME}-[0-9](#c10).${(qq)FILE_EXTENSION}(N); do
    tar -rf ${(qq)BASE_NAME}.tar \$file --remove-files
  done
EOF

[0-9](#c10)匹配 10 位十进制数字的序列。另请参阅与一位或多位数字或(不需要)[0-9]##相同的十进制数字序列组成该范围内的数字。[0-9](#c1,)<100000-9999999999>extendedglob

sshd在服务器上运行用户的登录 shell 来解释作为参数传递的代码。因为我们不知道它是什么(通常rootsh),所以我们只需编写该代码zsh来启动zshshell 并将zsh代码传递到标准输入上。

使用类似的此处文档可以更轻松地构造由远程 shell 解释的 shell 代码。由于EOF未加引号,本地 shell 将在本地执行扩展。

跟踪哪些扩展应该在本地完成以及哪些扩展应该由远程 shell 完成非常重要。

上面${(qq)BASE_NAME}是本地 shell 扩展的,我们使用(qq)参数扩展标志用单引号引用结果,以便远程 shell 将其视为文字字符串。

$file必须由远程 shell 扩展,因此我们为其添加前缀,\以便$file将文字传递到远程 shell。

如果zsh在远程计算机上不可用,但bash可以,您可以这样做(仍在zsh本地使用):

ssh root@$RMT_IP bash --norc << EOF
  shopt -s extglob nullglob # for +(...)
  export LC_ALL=C

  for file in ${(qq)BASE_NAME}-+([0-9]).${(qq)FILE_EXTENSION}; do
    tar -rf ${(qq)BASE_NAME}.tar "\$file" --remove-files
  done
EOF

bash没有相当于 的zshglobx(#c10)运算符,但使用 时extglob,它支持 ksh 的子集({10}(x)尽管不幸的是这里不是),包括+(x)匹配一个或多个x.这样+([0-9])将匹配一位或多位数字,而不仅仅是 10 位。

要匹配 10 位数字,您仍然可以这样做[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]

相关内容