在Bash管道中实现带文件名与文件分隔符的解压输出方案咨询
在Bash管道中实现带文件名与文件分隔符的解压输出方案咨询
嘿,这个问题我刚好有靠谱的解决思路,咱们一步步拆解来看~
你之前用bsdtar只能输出内容拿不到文件名,核心问题是直接批量解压输出了所有文件,没对每个子文件做单独的标记和文件名输出。其实只要在tar的--to-command里做一层遍历处理,就能同时拿到zip文件名、zip内部的子文件名、文件内容、分隔符这几个关键信息。
推荐实现方案(两种工具可选)
不管用unzip还是bsdtar都能实现,核心逻辑是:
- 用
tar --to-command对每个从tar包里提取的zip文件单独处理,tar会自动把当前处理的zip文件名放到$TAR_FILENAME变量里 - 遍历当前zip里的目标文件(比如*.html/*.xhtml)
- 对每个子文件,先输出带标记的文件名,再输出处理后的内容,最后输出自定义的文件分隔符
方案1:用unzip实现
直接把下面的命令放到你的bash管道里即可:
tar -xf ~/tar/0.tar --to-command ' # 拿到当前从tar里取出的zip文件名 CURRENT_ZIP="$TAR_FILENAME" # 列出zip内所有符合条件的文件,逐个处理 unzip -Z1 "$CURRENT_ZIP" "*.html" "*.xhtml" | while read -r SUB_FILE; do # 输出文件名(用独特标记开头,方便后续命令识别) echo "===FILE_NAME: $SUB_FILE===" # 解压并处理文件内容到标准输出 unzip -p "$CURRENT_ZIP" "$SUB_FILE" | iconv -f UTF-8 -t UTF-8//IGNORE | htmlq -tw # 输出文件分隔符(用独特标记,避免和内容冲突) echo -e "\n===END_OF_CONTENT===\n" done '
方案2:用bsdtar实现(替代unzip)
如果你的系统更习惯用bsdtar,把unzip的部分换成bsdtar的命令就行:
tar -xf ~/tar/0.tar --to-command ' CURRENT_ZIP="$TAR_FILENAME" # 用bsdtar列出zip内的目标文件 bsdtar -tf "$CURRENT_ZIP" --include="*.html" --include="*.xhtml" | while read -r SUB_FILE; do echo "===FILE_NAME: $SUB_FILE===" # 用bsdtar解压内容到标准输出 bsdtar -xO -f "$CURRENT_ZIP" "$SUB_FILE" | iconv -f UTF-8 -t UTF-8//IGNORE | htmlq -tw echo -e "\n===END_OF_CONTENT===\n" done '
为什么这个方案能满足你的需求?
- 文件内容:通过
unzip -p或bsdtar -xO直接输出到标准输出,完美衔接你原有的iconv和htmlq处理流程 - 文件名:用
===FILE_NAME: ...===的标记输出,和内容在同一条stdout流里,后续管道的命令可以通过匹配这个标记轻松提取文件名 - 文件分隔符:自定义的
===END_OF_CONTENT===标记,你可以换成任何不会和文件内容冲突的字符串,方便后续命令精准识别文件边界
对比你原来的bsdtar方案
你之前的命令直接批量解压所有符合条件的文件内容,没有逐个处理,所以丢失了每个子文件的文件名信息。现在的方案通过先列出zip内的文件、再逐个输出文件名+内容+分隔符,完美补上了这个缺口。
备注:内容来源于stack exchange,提问作者ghosts_in_the_code
相关产品推荐
相关产品推荐

