1

I have a file with below sample texts:

THIS(
is first
Line);
THAT(
is second line);
THIS(
is third
line);
THAT(
is 
fourth
line);

If you see the file, each sections are either starts with "THIS" or "THAT" and each section of texts are ending with a semicolon (;). I want a Unix command/script which will search for both "THIS" and "THAT" and copy all "THIS" sections to a file first_file, and all "THAT" sections to a different file second_file.

Example: The first file should contain:

THIS(
is first
Line);
THIS(
is third
line);

The second file should contain:

THAT(
is second line);
THAT(
is 
fourth
line);
  • Can you provide example of the input text? – Romeo Ninov Feb 7 at 9:54
  • In one line or they are in different lines? – Jetchisel Feb 7 at 10:43
2

Given

$ cat thisthat 
THIS(
is first
Line);
THAT(
is second line);
THIS(
is third
line);
THAT(
is 
fourth
line);

then

awk -vRS=';\n' 'BEGIN{ORS=RS} /^THIS/ {print > "these"} /^THAT/ {print > "those"}' thisthat

results

$ head these those 
==> these <==
THIS(
is first
Line);
THIS(
is third
line);

==> those <==
THAT(
is second line);
THAT(
is 
fourth
line);
|improve this answer|||||
  • You should mention that requires GNU awk for multi-char RS and no space after -v. – Ed Morton Feb 7 at 19:19
0

Using ed file editor but it requires that the second (empty) file be created before hand. The original file is named file1 in this example.

Create the second file is named file2

> file2

The heredoc

ed -s file1 << 'EOF'
H
g/^THAT($/;/^.*\;$/d
w
u
g/^THIS($/;/^.*\;$/d
0r file2
w file2
EOF

First line which feeds file1 to ed using a heredoc ed -s file1 << 'EOF'

Second line prints more verbose messages useful for errors. H

Third line Delete lines that starts with THAT( until the line that ends with a ;

g/^THAT($/;/^.*\;$/d

Fourth line Write the changes to file1 w

Fifth line Undo the changes ONLY in the buffer not the file1. u

Sixth line Delete lines that starts with THIS( until the line that ends with a ;

g/^THIS($/;/^.*\;$/d

Seventh line Add the remaining text in the buffer to the beginning of file2

0r file2

Eight line Write the changes file2. w file2


The one liner.

>file2; printf '%s\n' H 'g/^THAT($/;/^.*\;$/d' w u 'g/^THIS($/;/^.*\;$/d' '0r file2' 'w file2' | ed -s file1

Please note that ed edits the file in-place meaning files will be edited directly and it does not print the output to somewhere else, so test it first with some examples before running ed in your production file.

|improve this answer|||||
0

With any awk:

$ awk -v RS=';' 'NF{sub(/^\n/,""); print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line)
THIS(
is third
line)

$ cat second_file
THAT(
is second line)
THAT(
is
fourth
line)

or with GNU awk for multi-char RS and RT:

$ awk -v RS='(THIS|THAT)[^;]+;\n' -v ORS= '{$0=RT; print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line);
THIS(
is third
line);

$ cat second_file
THAT(
is second line);
THAT(
is
fourth
line);

Both solutions assume that your example is accurate and you never have ;s except at the end of the blocks (e.g. not within the (...) parts).

|improve this answer|||||
0

Tried with Awk Flag method

awk '/THIS/{f=1}/THAT/{f=0}f' file > file1(Contains "THIS" PATTERN)
awk '/THAT/{f=1}/THIS/{f=0}f' file > file2(Contains "THAT" PATTERN)

output

cat file1

THIS(
is first
Line);
THIS(
is third
line);



cat file2

    THAT(
    is second line);
    THAT(
    is 
    fourth
    line);
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.