将文本文件拆分为新文件

将文本文件拆分为新文件

我有一个以下格式的文本文件:

Model        1   
Atom….
Atom….
Atom….
ENDMDL
Model        2   
Atom….
Atom….
Atom….
ENDMDL
Model       n   
Atom….
Atom….
Atom….
ENDMDL

我需要将这个文件拆分为每个模型对应的文件。新文件的名称根据型号编号。

答案1

这可以很容易地使用一个小awk脚本。

#!/usr/bin/awk -f 
# Write sections of the input file to separate files
# Written by PM 2Ring 2016.06.14

BEGIN{outbase = "outfile"}

/^Model/{outname = outbase $2}

{print > outname}

outbase是基本文件名。它会附加型号,因此对于您的示例文件,将创建输出文件、等outfile1outfile2通过对脚本进行微小的更改,您可以outbase使用 awk 的选项从命令行进行设置-v

这个脚本的核心是

/^Model/{outname = outbase $2}

它表示:如果当前行以“Model”开头,则将字段 #2 的内容附加到字符串中outbase,并将结果分配给outname.

默认情况下,awk 逐行处理文件,使用空格作为字段分隔符将每一行分割成字段。

{print > outname}

只是将当前行打印到名称存储在 中的文件中outname


这个脚本足够小,可以在命令行上编写整个内容:

awk 'BEGIN{outbase = "outfile"}; /^Model/{outname = outbase $2}; {print > outname}' infile.txt

实际上,您可以提供多个输入文件参数,只要您没有重复的型号,它们就会被正确处理。

答案2

我可能会使用csplit.这适用于名为的文件file.txt

csplit -ksz file.txt '/^Model/' '{*}'
for xx in xx*
do
    newname=$(awk '{print $2; exit}' "$xx")
    test ! -f "$newname" && mv -f "$xx" "$newname"
done

根据 RE 拆分为多个部分csplitfile.txt文件名(默认情况下)命名为xx单调递增的数字后缀。我们依次查看每个文件并将它们重命名为文件中找到的型号。

xx*循环末尾匹配的任何文件都包含重复的型号(重命名是在先到先得基础)。

答案3

#!/bin/bash                                                                                                                                                                                                                                   

while read -r line                                                                                                                                                                                                                            
do                                                                                                                                                                                                                                            
    case $line in                                                                                                                                                                                                                             
        Model*)                                                                                                                                                                                                                               
            f="${line//[[:space:]]/}"
            touch "$f"  # file name without white spces                                                                                                                                                                                                                     
            ;;                                                                                                                                                                                                                                
        ENDMDL)                                                                                                                                                                                                                               
            :                                                                                                                                                                                                                                 
            ;;                                                                                                                                                                                                                                
        *)                                                                                                                                                                                                                                    
            echo "$line" >> "$f"                                                                                                                                                                                                              
            ;;                                                                                                                                                                                                                                
    esac                                                                                                                                                                                                                                      
done < "$1"

像这样的东西。您应该提供模型文件作为参数来运行它:./script_name models.txt

请注意,正如 @PM 2Ring 所提到的,这种方法很慢,特别是如果您有大文件。

相关内容