linux 有没有命令可以根据文件名将一个文件复制到多个其他文件?

linux 有没有命令可以根据文件名将一个文件复制到多个其他文件?

是否有一个 Linux 命令可以复制到、、、 、 等 文件a_b_c_d.jpg中,以便每个文件都是原始文件的副本?a.jpgb.jpgc.jpgd.jpg

它应该从原始名称中提取名称,以第一个 分隔_并以第一个 结尾.

答案1

#!/bin/sh

for name in *_*.jpg; do
    # Only care about regular files
    [ ! -f "$name" ] && continue

    # Do the following in a subshell to avoid affecting the original 
    # environment with "set -f" and setting IFS
    (
        set -f    # Turn off filename globbing (allows filename to contain e.g. *)
        IFS='_'   # Split unquoted strings on "_" only

        # Split the filename into parts (remove trailing ".jpg" first), and then
        # iterate over the parts, creating the symbolic links
        for part in ${name%.jpg}; do
            ln -s -- "$name" "$part.jpg"

            # To do copying instead, use:
            # cp -i -- "$name" "$part.jpg"
        done
    )
done

该脚本将迭代所有包含至少一个下划线且以.jpg当前目录结尾的文件名。对于每个这样的名称,它将用下划线分割名称并创建符号链接从分割名称的各个部分(.jpg添加文件名后缀)到原始文件(而不是副本)。

我选择创建符号链接而不是原始文件的真实副本,因为这不会占用太多额外的磁盘空间。如果您确实想进行复制,则可以在脚本的注释中找到相应的代码。

在包含两个文件的目录中运行它a_b_c_d.jpgABBA_hello there_misc.jpg产生

.
|-- ABBA.jpg -> ABBA_hello there_misc.jpg
|-- ABBA_hello there_misc.jpg
|-- a.jpg -> a_b_c_d.jpg
|-- a_b_c_d.jpg
|-- b.jpg -> a_b_c_d.jpg
|-- c.jpg -> a_b_c_d.jpg
|-- d.jpg -> a_b_c_d.jpg
|-- hello there.jpg -> ABBA_hello there_misc.jpg
`-- misc.jpg -> ABBA_hello there_misc.jpg

答案2

可能是这样的:

for FN in *.jpg; do IFS="_."; AR=($FN); for i in "${AR[@]}"; do [ ! "$i" = "jpg" ] &&  echo cp "$FN" "$i".jpg; done; done
cp a_b_c_d.jpg a.jpg
cp a_b_c_d.jpg b.jpg
cp a_b_c_d.jpg c.jpg
cp a_b_c_d.jpg d.jpg

您可能想要添加一些更多的错误检查、IFS 安全防护、echo一旦您满意就将其删除等等...

编辑根据 Kusalananda 的评论进行编辑。

for FN in *.jpg; do IFS="_"; for i in ${FN%.jpg}; do echo cp "$FN" "$i".jpg; done; done

答案3

一个简单的方法是...

for x in a b c d
do
  cp a_b_c_d.jpg $x.jpg
done

我冒昧地猜测,您希望以更编程的方式执行此操作,而不必指定该a b c d部分,而是从文件名中获取它。

如果是这种情况,那么您将需要获取文件名并将其拆分两次,首先根据 的出现来.获取文件扩展名,然后再次根据 来_获取文件名。这可以使用以下方法完成IFS以及对文件名数组的循环,就像我在上面的原始示例中所做的那样。

答案4

好吧,我写了简单的脚本

#!/bin/bash
for filename in *_*.jpg; do
   n=$(echo "$filename" | awk -F '_' '{print NF}')
   for ((i=1; i<$n;i++)) ;do
      cp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$i"'}')".jpg
   done
   cp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$n"'}')"
done

它将搜索jpg至少具有一个_.然后使用cp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$i"'}')".jpg它将复制原始文件。然而最后一个参数包含.jpg扩展名,所以我在 for 循环之外单独写了它,没有.jpg.扩大。

相关内容