Linux bash 如何在复制命令中使用通配符的结果作为文件名

Linux bash How to use a result of a wildcard as a file name in a copy command

我正在编写一个 Linux 脚本来将文件夹结构中的文件复制到一个文件夹中。我想使用不同的文件夹名称作为文件名的前缀。

我当前的脚本如下所示。但是,我似乎找不到使用通配符中的文件夹名称作为文件名的方法;

for f in /usr/share/storage/*/log/myfile.log*; do cp "$f" /myhome/docs/log/myfile.log; done

我现有的文件夹 structure/files 如下,我希望将文件复制为;

>/usr/share/storage/100/log/myfile.log    -->    /myhome/docs/log/100.log
>/usr/share/storage/100/log/myfile.log.1  -->    /myhome/docs/log/100.log.1
>/usr/share/storage/102/log/myfile.log    -->    /myhome/docs/log/102.log
>/usr/share/storage/103/log/myfile.log    -->    /myhome/docs/log/103.log
>/usr/share/storage/103/log/myfile.log.1  -->    /myhome/docs/log/103.log.1
>/usr/share/storage/103/log/myfile.log.2  -->    /myhome/docs/log/103.log.2

一个选择是将 for 循环包装在另一个循环中:

for d in /usr/share/storage/*; do
    dir="$(basename "$d")"

    for f in "$d"/log/myfile.log*; do
        file="$(basename "$f")"
        # test we found a file - glob might fail
        [ -f "$f" ] && cp "$f" /home/docs/log/"${dir}.${file}"
    done
done
for f in /usr/share/storage/*/log/myfile.log*; do cp "$f" "$(echo $f | sed -re 's%^/usr/share/storage/([^/]*)/log/myfile(\.log.*)$%/myhome/docs/log/%')"; done

您可以使用正则表达式匹配来提取所需的组件,但简单地更改为 /usr/share/storage 可能更容易,这样所需的组件始终是 第一个 一个在路上。

完成后,只需使用各种参数扩展运算符来提取您要使用的路径和文件名部分即可。

cd /usr/share/storage
for f in */log/myfile.log*; do
    pfx=${f%%/*}  # 100, 102, etc
    dest=$(basename "$f")
    dest=$pfx.${dest#*.}
    cp -- "$f" /myhome/docs/log/"$pfx.${dest#*.}"
done