将文本文件拆分为给定模式之前和之后的内容

将文本文件拆分为给定模式之前和之后的内容

我希望能够将一个文本文件拆分为两个文件,这样如果文件中存在该模式,则第一个输出将包含给定模式之前的所有行(但不包括该模式),如果不存在该模式,则第一个输出将包含整个输入文件。第二个文件应该是模式之后的所有行或空文件。

file1.txt:
a
b
c

$ split.sh 文件1.txt "b"

file1.txt.before:
a

file1.txt.after:
c

$ split.sh file1.txt "d"

file1.txt.before:
a
b
c

file1.txt.after:

我尝试了不同的 sed 命令,我想到最接近的方法是:

sed "1,/$2/!d" < $1 > $1.before
sed "1,/$2/d" < $1 > $1.after

但这存在一些问题: - 之前的文件缺少输入文件的第一行 - 之前的文件包含模式

答案1

使用拆分对于这样的事情。

CSPLIT(1)                        User Commands                       CSPLIT(1)

NAME
       csplit - split a file into sections determined by context lines

-f, --prefix=PREFIX
          use PREFIX instead of 'xx'
--suppress-matched
          suppress the lines matching PATTERN

关于命令的正则表达式部分:

Each PATTERN may be:

   INTEGER
          copy up to but not including specified line number

   /REGEXP/[OFFSET]
          copy up to but not including a matching line

   %REGEXP%[OFFSET]
          skip to, but not including a matching line

   {INTEGER}
          repeat the previous pattern specified number of times

   {*}    repeat the previous pattern as many times as possible

   A line OFFSET is a required '+' or '-' followed by a positive integer.

命令

csplit <file.txt> /<string>/ '{*}'

<file.txt>将根据查找的频率将其拆分为多个部分<string>'{*}'将重复搜索并为每个出现创建多个文件。默认情况下,文件将被命名为xx{number};使用--prefix选项可以更改它。添加--suppress-matched将从文件中省略搜索字符串。

答案2

以下是使用 Awk 的一种方法:

awk -v pattern='^b' '
  NR==1 {suff = ".before"} $0 ~ pattern {suff = ".after"; next} {print > FILENAME suff}
' file1.txt

前任。

awk -v pattern='^b' 'NR==1 {suff = ".before"} $0 ~ pattern {suff = ".after"; next} {print > FILENAME suff}' file1.txt

给予

$ head file1.txt*
==> file1.txt <==
a
b
c

==> file1.txt.after <==
c

==> file1.txt.before <==
a

相关内容