我有一个包含 417 个文件夹路径的列表,我需要按特定顺序合并这些路径,以便其中的文件相互覆盖。将来当我对文件夹进行更改时,我可能需要再次执行此操作,因此我绝对不会手动执行此操作,我想学习如何编写执行此操作的脚本。
另外,如果脚本可以将所有内容转换为小写,那就太好了,我对这些所做的就是不压缩地压缩它们,然后用 -LL 解压缩它们,但如果我不必再这样做,那就太好了因为花了一段时间(17GB)。
清单就是这样的
“/小路/”
“/小路/”
“/小路/”
(如果有人好奇的话,这是为了合并 morrowind/openmw 的一堆 mod)
答案1
像这样的东西应该有效:
while IFS= read -r dir
do
cp -f "$dir"/* target
done < list
其中list
是目录列表,target
是要将文件复制到的目录。列表中后面出现的目录中的文件将覆盖列表中前面出现的目录中的文件 -
cp -f
为复制程序指定“强制覆盖”选项。这假设:
- 目录名称不包含换行符。 (如果这样做,您将无法在简单的文本文件中列出它们。)
- 列表文件实际上并不包含引号。
- 每个目录只有(普通)文件,没有子目录或特殊的东西。
- 没有文件名开头
.
。
答案2
cp -r $(<sources) target/
应该管用。
这假定路径已在文件中列出sources
。
每个路径可以是目录或文件的路径,但sources
文件中的任何路径都不能包含任何空格(空格、制表符、换行符等)或 shell 通配符(例如*
或?
),并且不应将它们括起来(除非实际名称包含引号)。
你也可以使用类似的东西
xargs -t -Isrc cp -r src target/ <sources
这将允许使用更奇特的文件名,但不允许使用换行符的文件名。
以下是一个简短的bash
脚本,它将一组文件名转换为小写(应该echo
删除 来执行实际的重命名,它在那里以便您可以看到会发生什么)。
#!/bin/bash
for path in "$@"; do
dir="${path%/*}"
name="${path##*/}"
if [[ ! "$path" -ef "$dir/${name,,}" ]]; then
echo mv "$path" "$dir/${name,,}"
fi
done
如果两个路径引用同一个文件,则测试-ef
返回 true(在这种情况下不应发生重命名)。变量${name,,}
替换是实际小写的作用。
您可以将其应用到如下目录:
$ find target -type f -exec bash tolower.sh {} +