BASH - 根据条件将文件拆分为多个文件

时间:2018-04-04 09:37:31

标签: bash awk sed split grep

我有一个文件(input.txt),结构如下:

>day_1
ABC
DEF
GHI
>day_2
JKL
MNO
PQR
>day_3
STU
VWX
YZA
>month_1
BCD
EFG
HIJ
>month_2
KLM
NOP
QRS
...

我想将此文件拆分为多个文件(day.txt; month.txt; ...)。每个新文本文件将包含所有“标题”行(以>开头的行)及其内容(两个标题行之间的行)。

因此,

day.txt将是:

>day_1
ABC
DEF
GHI
>day_2
JKL
MNO
PQR
>day_3
STU
VWX
YZA

month.txt

>month_1
BCD
EFG
HIJ
>month_2
KLM
NOP
QRS

在这种情况下,我无法使用split -l因为每个类别(日,月等)的行数不相同。但是,每个子类别具有相同的行数(= 3)。

4 个答案:

答案 0 :(得分:2)

编辑: 根据OP现在增加1个解决方案。

awk -F'[>_]' '/^>/{file=$2".txt"} {print > file}'  Input_file

<强> 说明:

awk -F'[>_]' '        ##Creating field separator as > or _ in current lines.
/^>/{ file=$2".txt" } ##Searching a line which starts with > if yes then creating a variable named file whose value is 2nd field".txt"
    { print > file  } ##Printing current line to variable file(which will create file name of variable file's value).
'  Input_file         ##Mentioning Input_file name here.

关注awk可能对您有帮助。

awk '/^>day/{file="day.txt"} /^>month/{file="month.txt"} {print > file}' Input_file

答案 1 :(得分:1)

您可以将记录分隔符设置为>,然后根据$1给出的类别设置文件名。

$ awk -v RS=">" 'NF {f=$1; sub(/_.*$/, ".txt", f); printf ">%s", $0 > f}' input.txt

$ cat day.txt
>day_1
ABC
DEF
GHI
>day_2
JKL
MNO
PQR
>day_3
STU
VWX
YZA

$ cat month.txt
>month_1
BCD
EFG
HIJ
>month_2
KLM
NOP
QRS

答案 2 :(得分:0)

由于每个子类别由相同数量的行组成,因此您可以使用grep&#39; s -A / --after标志来指定在a之后匹配的行数报头中。

因此,如果您事先知道类别列表,则只需要查看其子类别的标题,将其内容重定向到正确的文件:

lines_by_subcategory=3 # number of lines *after* a subcategory's header
for category in "month" "day"; do
    grep ">$category" -A $lines_by_subcategory input.txt >> "$category.txt"
done

你可以try it here

请注意,这不是最有效的解决方案,因为它必须为每个类别浏览一次输入。其他解决方案可以在一次浏览中浏览内容并将每个子类别重定向到各自的文件中。

答案 3 :(得分:0)

这是>name_number格式

的通用解决方案
$ awk 'match($0, /^>[^_]+_/){k = substr($0, RSTART+1, RLENGTH-2);
         if(!(k in a)){close(op); a[k]; op=k".txt"}}
       {print > op}' ip.txt
  • match($0, /^>[^_]+_/)如果行在行首处匹配>name_
    • k = substr($0, RSTART+1, RLENGTH-2)保存name部分
    • 如果在数组中找不到密钥,则
    • if(!(k in a))
    • a[k]为数组添加键
    • op=k".txt"输出文件名
    • close(op),以防有太多文件要写
  • print > op将输入记录打印到op
  • 中保存的文件名
相关问题