我的文件名为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文件。
答案 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