使用前置和附加文件连接目录中的多个文件

使用前置和附加文件连接目录中的多个文件

我有一个文件目录,需要将两个文件合并到每个文件中。为了简单起见,我们使用intro.txtoutro.txt

因此,对于文件file1.txtfile3.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.txtfile3.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.txtfile1.txtfile1_complete.txtcat

答案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。我们使用而不是保留文件的属性(所有者、组、权限等)。(...)$fcpmv

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

相关内容