Bash从另一个外部文件中读取文件列表后,将多个文件合并为单个文件

时间:2015-05-19 22:08:44

标签: bash

我的文件名为filesList.txt,其中包含需要合并到单个文件中的所有文件的列表。

filesList.txt
------------------
../../folder/a.js
../../folder/b.js
../../folder/c.js
../../folder/d.js

当前我正在运行以下命令。

cp filesList.txt filesList.sh
chmod 777 filesList.sh
vim filesList.sh
cat
../../folder/a.js
../../folder/b.js
../../folder/c.js
../../folder/d.js
> output.txt

运行vim命令j10,使上面的多行文件成为单行,如下所示

cat ../../folder/a.js ../../folder/b.js ../../folder/c.js ../../folder/d.js > output.txt

使用:wq在vim中保存并退出文件 并运行./fileList.sh以创建单个output.text文件,其中包含完全相同的订单文件。

我的问题是我需要使用什么命令来创建一个bash文件,该文件逐行创建文件的外部列表(filesList.txt)并生成单个文件及其内容。因此,每次我需要合并文件时,我都不必将filesList.txt文件转换为filesList.sh文件。

1 个答案:

答案 0 :(得分:3)

一个面向行的文件在这里是一个糟糕的选择(在“任何可以控制文件名的攻击者都可以将任意文件注入到你的输出中”的感觉不好;你可能不想冒险那个人弄清楚如何创建与您的glob匹配的新.js文件然后可以通过创建/etc/passwd../../$'\n'/etc/passwd$'\n'/hello.js引入列表。相反,通过NUL分隔值,并使用xargs -0(非POSIX扩展,但是主要操作系统供应商提供的流行扩展)将这些扩展为参数。

printf '%s\0' ../../folder/*.js >filesList.nsv # generate file w/ null-separated values
xargs -0 cat <filesList.nsv >output.txt        # combine to argument list split on NUL

顺便说一句,如果你想以递归方式生成文件列表,那么第一部分就会变成:

find ../../folder -name '*.js' -print0 >filesList.nsv

...如果您对filesList.nsv没有任何其他需求,我会完全避免它并直接生成output.txt

find ../../folder -name '*.js' -exec cat '{}' + >output.txt

如果你必须使用换行符,但你有GNU xargs,至少使用xargs -d $'\n'来处理它们以试图避免在库存xargs或更多天真中找到的其他引用相关的错误bash中的做法:

printf '%s\n' ../../folder/*.js >filesList.txt # generate w/ newline-separated values
xargs -d $'\n' cat <filesList.txt >output.txt  # combine on those values

如果您没有GNU xargs,那么您可以在shell中自己实现:

# Newline-separated input
while IFS= read -r filename; do
  cat "$filename"
done <filesList.txt >output.txt

# ...or NUL-separated input
while IFS= read -r -d '' filename; do
  cat "$filename"
done <filesList.txt >output.txt