我在名为的文件中有一个文件名列表list_of_files.txt
。
我想将该列表中每个文件的内容复制到另一个名为的文件中all_compounds.sdf
。
我应该如何从命令行执行此操作?
我在名为的文件中有一个文件名列表list_of_files.txt
。
我想将该列表中每个文件的内容复制到另一个名为的文件中all_compounds.sdf
。
我应该如何从命令行执行此操作?
Answers:
不要使用简单的命令替换来获取文件名(文件名很容易用空格和其他特殊字符破坏)。使用类似xargs
:
xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf
或while read
循环:
while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf
为了安全地使用命令替换,至少将其设置IFS
为换行符并禁用globbing(通配符扩展):
(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)
圆括号()
将在子外壳程序中运行,以便您当前的外壳程序不受这些更改的影响。
快速而肮脏的方式...
cat $(cat list_of_files.txt) >> all_compounds.sdf
请注意:这仅在列表中的文件名表现良好时才有效-如果它们中包含空格,换行符或任何对Shell具有特殊含义的字符,则会出错-请使用此答案以获得可靠的结果)
cat
CON 猫 enates文件。它还会打印其内容。command2 $(command1)
您可以将command1
(cat list...
)的输出传递给command2
(cat
),以连接文件。然后使用重定向>>
将输出发送到文件,而不是打印到stdout。如果要查看输出,请tee
改用:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(如果您的文件已经存在,我将使用>>
代替该开关,>
并将其tee
与该-a
开关一起使用-如果该文件已经存在,它将附加到文件中而不是覆盖它)
cat
整个列表作为一个参数。
尽管GNU awk
是文本处理实用程序,但它允许通过system()
调用运行外部Shell命令。我们可以这样利用我们的优势:
$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt
这里的想法很简单:我们逐行读取文件,然后从每一行中创建格式化的字符串cat "File name.txt"
,然后将其传递给system()
。
它在起作用:
$ ls
file1.txt file2.txt file3 with space.txt file_list.txt
$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3
因此,我们已经完成了大部分任务-将所有文件打印在列表上。剩下的很简单:将最终的输出重定向到带有>
操作符的文件到摘要文件中。
awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
"$(cat list_of_files.txt)"