是否有一个 Linux 命令可以复制到、、、 、 等 文件a_b_c_d.jpg
中,以便每个文件都是原始文件的副本?a.jpg
b.jpg
c.jpg
d.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.jpg
会ABBA_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
.扩大。