我有一个名为的文件path.txt
,其中包含一些文件的目录路径作为行:
../../data/first.gz
../../data/second.gz
我想读取path.txt
,读取每一行,将这些文件(.gz 文件)的内容存储到一个新文件中。
我在这里发现了类似的问题awk 命令用于读取包含另一个文件内容的文件和此代码(文件名已更改以匹配我的数据)。
awk '{ while ((getline a < $0) > 0) print a }' path.txt >> newfile
我是 awk 和 bash 的新手。我不知道如何修改上面的代码以使用 zcat 或类似的方式打开 zip 文件并将内容打印到 newfile。有人可以帮我修改代码或提出新的代码吗?提前致谢。
答案1
使用xargs
with (这里假设其和选项zcat
是 GNU 实现):-r
-d
<path.txt xargs -rd'\n' zcat -- >>output
要将zcat
每个 .gz 文件输出到单独的输出文件中,您实际上根本不需要在此处使用 shell 循环,只需调用内联脚本,如下所示:
<infile xargs -rd'\n' -I{} sh -c 'zcat -- "$1" >output."${1##*/}"' xargs-sh {}
答案2
这里不需要awk
,一个简单的 shell 循环就足够了:
while IFS= read -r gz; do
zcat < "$gz"
done < path.txt >> newfile
或者,将每个文件放入自己的文件中:
while IFS= read -r gz; do
zcat < "$gz" > "${gz%.gz}.uncompressed"
done < path.txt
这里删除.gz
后缀(如果有),并添加.uncompressed
后缀以避免破坏名称不以.gz
.您还可以设置noclobber
选项 ( set -o noclobber
) 以避免破坏现有文件。
使用重定向而不是将文件名作为参数传递,可以避免zcat
以 开头的文件名出现问题-
,也可以避免在无法打开输入文件时创建输出文件。
答案3
一个简单的方法,因为中的“cat”zcat
代表“连接”,因此zcat
需要一个文件列表来连接
zcat -- $(cat path.txt) > newfile
然而,这有点危险,因为 path.txt 可能包含带有空格的路径 - 并且您的 bash 会认为空格分隔参数。突然,../path/to/My document.txt.gz
变成../path/to/My
和document.txt.gz
,而这两个都不存在!
IFS=$'\n'; zcat -- $(cat path.txt) > newfile
因为您只希望该设置应用于这一行,而不是 shell 会话的其余部分:
( IFS=$'\n'; zcat -- $(cat path.txt) > newfile )
名为的文件*
也将扩展到当前目录中的所有非隐藏文件名。
因此,您想告诉 shell 它应该只关心换行符作为参数分隔符,并禁用通配符:
( IFS=$'\n'; set -o noglob; zcat -- $(cat path.txt) > newfile )
(顺便说一句,文件名也可以包含换行符,但我认为根据未处理的文件列表,这是一个无法解决的问题)
正如 Stéphane 指出的,用 forzsh
代替bash
,有更短的方法可以做同样的事情:
zcat -f -- ${(f)"$(<path.txt)"}
因为zsh
它是我的“家”shell,所以我很高兴了解到${(f)"somestring"}
:它somestring
在换行符处分裂;$(< path.txt)
实际上与 相同$(cat path.txt)
,但不需要cat
输出文件的内容 – 该功能是 shell 的一部分。