我正在处理位于不同目录中的几个文件,需要将它们压缩为单独的 .gz 文件。我还需要将压缩文件移动到单个目录中,同时保留原始文件。
有没有办法使用 gzip 命令和包含我想要压缩的文件的所有文件路径列表的文件来做到这一点?
如果这有点冗长,请原谅...我对 Linux 还很陌生,想不出更有效的措辞方式。
答案1
假设文件列表存储在名为文件列表(每行只有一个文件路径),并且您希望将压缩文件存储在压缩文件,这个bash脚本将实现预期的结果:
#!/bin/bash
while IFS= read file; do
gzip -c "$file" > "zipdir/$(basename "$file").gz"
done < filelist
在 bash/dash 中,您还可以将上述内容转换为单行代码:
while IFS= read file; do gzip -c "$file" > "zipdir/$(basename "$file").gz"; done < filelist
在其他 shell 中(例如 tcsh 或 zsh)
bash -c 'while IFS= read file; do gzip -c "$file" > "zipdir/$(basename "$file").gz"; done < filelist'
将会完成这项工作。
如果没有 bash,可以用 dash 代替。
怎么运行的
... < filelist
重定向内容文件列表到...
。while IFS= read file; do ... done
遍历文件列表中的行,将当前处理的行的内容存储在变量中文件并执行...
。IFS=
修改内部文件分隔符。这是为了正确处理多个前导空格和尾随空格。gzip -c "$file" > "zipdir/$(basename "$file").gz"
压缩当前处理的文件,并将输出存储在同名文件中,另加.gz目录中的扩展压缩文件。这里
basename "$file"
从文件路径中提取裸文件名。
答案2
我认为不gzip
支持从文件读取路径。解决方法是将所有目标文件放入存档 (tar) 或执行多次。
如果目标目录不受容量或传输速度的限制,则可能的解决方案是在目标文件夹中压缩文件之前移动文件,如这个答案。
否则,您将一次只能读取一个文件名,并在读取过程中压缩并创建其文件夹。
创建文件夹结构
TARGET=~/tmp/out
while read line; do
dirname "$line" ;
done < list.txt | sort -u |
xargs -I% echo mkdir -p "$TARGET/%"
## out: ##
mkdir /home/jaroslav/tmp/out/code/bash
mkdir /home/jaroslav/tmp/out/recipes
mkdir /home/jaroslav/tmp/out/samba
mkdir /home/jaroslav/tmp/out/wikipedia
复制文件
while read line; do
gzip -c "$SOURCE/$line" > "$TARGET/$line.gz"
done < list.txt
命令
- dirname:删除文件路径的最后一部分,保留目录
- read [arg] < file: 从文件中一次读取一行并将其存储在 shell 变量 arg 中
- sort -u:删除重复的条目(保留
u
唯一性) - xargs -I% :对管道 (|) 中的每个元素 (目录名) 执行一次命令 (echo ....)
- gzip -c in > out:压缩 in 并写入 stdout(-c)。> 将 stdin 重定向到名为 out 的文件。