我有一个文件目录,需要将两个文件合并到每个文件中。为了简单起见,我们使用intro.txt
和outro.txt
。
因此,对于文件file1.txt
,file3.txt
我想要包含以下内容的新文件
intro.txt
+file1.txt
+outro.txt
intro.txt
+file2.txt
+outro.txt
intro.txt
+file3.txt
+outro.txt
分别。
对于单个文件我会做
cat intro.txt file1.txt outro.txt > output.txt
对于许多文件,如何才能最好地完成此操作?
答案1
循环正文文件,用于将cat
页眉和页脚文件与每个正文文件连接起来,输出到新名称:
for body in file*.txt; do
cat intro.txt "$body" outro.txt >"${body%.txt}-complete.txt"
done
这会将完成的文件写入诸如file1-complete.txt
,之类的名称file2-complete.txt
。输出文件名是通过.txt
从名称中删除已知的文件名后缀$body
并附加-complete.txt
在末尾来构造的。
请注意,任何现有的输出文件都会被覆盖。
答案2
我假设您的“meat”文件的名称(您将它们称为file1.txt
)file3.txt
可以被 glob 表达式覆盖,例如file*.txt
.
在这种情况下,以下内容应该可以工作(我假设这里是 Bash 风格的字符串操作,但适应其他 shell 应该很简单):
for f in file*.txt; do
out="${f/%.txt/_complete.txt}";
cat intro.txt "$f" outro.txt > "$out";
done
这将循环遍历与 glob 表达式匹配的所有文件,并通过将后缀替换为(因此将变为)来file*.txt
创建存储在 shell 变量 中的新文件名。然后将当前输入文件的开头和结尾放入新文件中。$out
.txt
_complete.txt
file1.txt
file1_complete.txt
cat
答案3
和zsh
:
for f (file<1-3>.txt) (cp =(cat intro.txt - outro.txt) $f) < $f
=(cat intro.txt - outro.txt)
扩展为包含该命令输出的临时文件的路径cat
。
我们使用重定向来代替,以便在无法打开读取时取消cat intro.txt $f outro.txt
整个子 shell。我们使用而不是保留文件的属性(所有者、组、权限等)。(...)
$f
cp
mv
cp
如果失败的话仍然会运行cat
。
你可以这样做:
for f (file<1-3>.txt) (){
cat cat intro.txt $f outro.txt > $1 &&
cp -- $1 $f
} =(:)
以避免它。
ksh93
有一个专门的重定向操作符来处理这种事情:
for f in file[123].txt; do
cat intro.txt "$f" outro.txt >; "$f"
done
where>;
将输出写入临时文件,如果命令成功,该临时文件将重命名为目标。不过,您可能会丢失文件的一些原始属性。
(请注意,[123]
匹配这 3 个字符中的任何一个 ([1-3]
会更像[123²¹¼½١٢۱۲߁߂१२১২੧੨૧૨୧୨௧௨౧౨౹౺౼౽೧೨൧൨෧෨๑๒໑໒༡༢༪༫၁၂႑႒፩፪១២៱៲᠑᠒᥇᥈᧑᧒᧚᪁᪂᪑᪒᭑᭒᮱᮲᱁᱂᱑᱒₁₂⅐⅑⅒⅓⅔⅕⅖⅙⅛⅟①②⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓾❶❷❿➀➁➉➊➋➓〡〢㉈㉉㉑㉒㉓㉔㉕㉖㉗㉘㉙㋀㋁㋉㋊㋋㍙㍚㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㏠㏡㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼꘡꘢꣑꣒꤁꤂꧑꧒꧱꧲꩑꩒꯱꯲12
答案4
在目录中创建一个文件名数组,用于cat
合并多个文件
array=($(ls file* | xargs -n 1 basename))
for filename in "${array[@]}"
do
cat intro.txt $filename outro.txt > final_$filename
done