Delete newline characters between patterns
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
Yes, there is no bar
complementing foo
at the end of the file
The required output is
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
So, remove all newline characters, between ^foo
and ^bar
or between ^foo
and the end of file
where there is no bar
text-processing awk sed perl
add a comment |Â
up vote
0
down vote
favorite
foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
Yes, there is no bar
complementing foo
at the end of the file
The required output is
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
So, remove all newline characters, between ^foo
and ^bar
or between ^foo
and the end of file
where there is no bar
text-processing awk sed perl
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
Yes, there is no bar
complementing foo
at the end of the file
The required output is
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
So, remove all newline characters, between ^foo
and ^bar
or between ^foo
and the end of file
where there is no bar
text-processing awk sed perl
foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
Yes, there is no bar
complementing foo
at the end of the file
The required output is
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
So, remove all newline characters, between ^foo
and ^bar
or between ^foo
and the end of file
where there is no bar
text-processing awk sed perl
text-processing awk sed perl
edited Sep 18 at 9:25
ñÃÂsýù÷
16k92563
16k92563
asked Sep 17 at 0:17
GypsyCosmonaut
718628
718628
add a comment |Â
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
2
down vote
accepted
With awk
:
awk '
$0 == "foo" if (sep) print ""; sep = ""; inside = 1; next
$0 == "bar" inside = 0; next
inside printf "%s", sep $0; sep = " "
END if (sep) print ""'
To match on lines with foo
as the first word, replace $0 == "foo"
with $1 == "foo"
; to match on lines starting with foo
, replace with /^foo/
(short for $0 ~ /^foo/
).
add a comment |Â
up vote
2
down vote
Perl to the rescue!
perl -ne '
if ($e = /^foo$/ .. /^bar$/)
if ($e =~ /E/) print "n"
else
chomp;
print " " if $e > 2;
print if $e > 1;
' -- input.txt
-n
reads the input line by line..
is the range operator, it returns the relative line number for each line in a block. The last line hasE0
appended to it.
Why are>2
and>1
used here and what are they doing basically?
â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.$e > 2
excludes the first two lines of each block,$e > 1
excludes only the first (foo) one.
â choroba
Sep 17 at 1:30
1
Yes, you can move the$e > 1
one level up:perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
add a comment |Â
up vote
2
down vote
You could do this way also:
a) This is POSIX-sed
compliant code wherein we store the mid-range lines (!/foo/ and !/bar/) in the hold area.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!H;$!d;
s/.*//;x;s/^n//;y/n/ /
' input-file.txt
b) and with Perl
as shown
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Explanation:
- skip non-interesting lines or lines that fall out of range. A range is defined as beginning with a line containing
/foo/
and ending with/bar/
, both occurring on separate lines. - Once we are in the range, then perform separate actions based on what line we are in.
- For lines that are not /foo/, neither /bar/, and neither eof : store the line in the array
@A
. After storing, go back for reading the next record provided not eof. - Only for the end of range, i.e.,
/bar/
oreof
, we take the action of printing what's in@A
and also emptying it, in preparation for the next gathering cycle.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
With awk
:
awk '
$0 == "foo" if (sep) print ""; sep = ""; inside = 1; next
$0 == "bar" inside = 0; next
inside printf "%s", sep $0; sep = " "
END if (sep) print ""'
To match on lines with foo
as the first word, replace $0 == "foo"
with $1 == "foo"
; to match on lines starting with foo
, replace with /^foo/
(short for $0 ~ /^foo/
).
add a comment |Â
up vote
2
down vote
accepted
With awk
:
awk '
$0 == "foo" if (sep) print ""; sep = ""; inside = 1; next
$0 == "bar" inside = 0; next
inside printf "%s", sep $0; sep = " "
END if (sep) print ""'
To match on lines with foo
as the first word, replace $0 == "foo"
with $1 == "foo"
; to match on lines starting with foo
, replace with /^foo/
(short for $0 ~ /^foo/
).
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
With awk
:
awk '
$0 == "foo" if (sep) print ""; sep = ""; inside = 1; next
$0 == "bar" inside = 0; next
inside printf "%s", sep $0; sep = " "
END if (sep) print ""'
To match on lines with foo
as the first word, replace $0 == "foo"
with $1 == "foo"
; to match on lines starting with foo
, replace with /^foo/
(short for $0 ~ /^foo/
).
With awk
:
awk '
$0 == "foo" if (sep) print ""; sep = ""; inside = 1; next
$0 == "bar" inside = 0; next
inside printf "%s", sep $0; sep = " "
END if (sep) print ""'
To match on lines with foo
as the first word, replace $0 == "foo"
with $1 == "foo"
; to match on lines starting with foo
, replace with /^foo/
(short for $0 ~ /^foo/
).
edited Sep 17 at 7:33
answered Sep 17 at 7:00
Stéphane Chazelas
287k53528867
287k53528867
add a comment |Â
add a comment |Â
up vote
2
down vote
Perl to the rescue!
perl -ne '
if ($e = /^foo$/ .. /^bar$/)
if ($e =~ /E/) print "n"
else
chomp;
print " " if $e > 2;
print if $e > 1;
' -- input.txt
-n
reads the input line by line..
is the range operator, it returns the relative line number for each line in a block. The last line hasE0
appended to it.
Why are>2
and>1
used here and what are they doing basically?
â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.$e > 2
excludes the first two lines of each block,$e > 1
excludes only the first (foo) one.
â choroba
Sep 17 at 1:30
1
Yes, you can move the$e > 1
one level up:perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
add a comment |Â
up vote
2
down vote
Perl to the rescue!
perl -ne '
if ($e = /^foo$/ .. /^bar$/)
if ($e =~ /E/) print "n"
else
chomp;
print " " if $e > 2;
print if $e > 1;
' -- input.txt
-n
reads the input line by line..
is the range operator, it returns the relative line number for each line in a block. The last line hasE0
appended to it.
Why are>2
and>1
used here and what are they doing basically?
â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.$e > 2
excludes the first two lines of each block,$e > 1
excludes only the first (foo) one.
â choroba
Sep 17 at 1:30
1
Yes, you can move the$e > 1
one level up:perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Perl to the rescue!
perl -ne '
if ($e = /^foo$/ .. /^bar$/)
if ($e =~ /E/) print "n"
else
chomp;
print " " if $e > 2;
print if $e > 1;
' -- input.txt
-n
reads the input line by line..
is the range operator, it returns the relative line number for each line in a block. The last line hasE0
appended to it.
Perl to the rescue!
perl -ne '
if ($e = /^foo$/ .. /^bar$/)
if ($e =~ /E/) print "n"
else
chomp;
print " " if $e > 2;
print if $e > 1;
' -- input.txt
-n
reads the input line by line..
is the range operator, it returns the relative line number for each line in a block. The last line hasE0
appended to it.
edited Sep 17 at 1:47
answered Sep 17 at 0:43
choroba
24.9k34168
24.9k34168
Why are>2
and>1
used here and what are they doing basically?
â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.$e > 2
excludes the first two lines of each block,$e > 1
excludes only the first (foo) one.
â choroba
Sep 17 at 1:30
1
Yes, you can move the$e > 1
one level up:perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
add a comment |Â
Why are>2
and>1
used here and what are they doing basically?
â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.$e > 2
excludes the first two lines of each block,$e > 1
excludes only the first (foo) one.
â choroba
Sep 17 at 1:30
1
Yes, you can move the$e > 1
one level up:perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
Why are
>2
and >1
used here and what are they doing basically?â GypsyCosmonaut
Sep 17 at 1:13
Why are
>2
and >1
used here and what are they doing basically?â GypsyCosmonaut
Sep 17 at 1:13
It's numerical comparison.
$e > 2
excludes the first two lines of each block, $e > 1
excludes only the first (foo) one.â choroba
Sep 17 at 1:30
It's numerical comparison.
$e > 2
excludes the first two lines of each block, $e > 1
excludes only the first (foo) one.â choroba
Sep 17 at 1:30
1
1
Yes, you can move the
$e > 1
one level up: perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
Yes, you can move the
$e > 1
one level up: perl -ne 'if ($e = /^foo$/ .. /^bar$/) if ($e =~ /E/) print "n" elsif ($e > 1) chomp; print " " if $e > 2; print; ' -- file
â choroba
Sep 17 at 1:49
add a comment |Â
up vote
2
down vote
You could do this way also:
a) This is POSIX-sed
compliant code wherein we store the mid-range lines (!/foo/ and !/bar/) in the hold area.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!H;$!d;
s/.*//;x;s/^n//;y/n/ /
' input-file.txt
b) and with Perl
as shown
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Explanation:
- skip non-interesting lines or lines that fall out of range. A range is defined as beginning with a line containing
/foo/
and ending with/bar/
, both occurring on separate lines. - Once we are in the range, then perform separate actions based on what line we are in.
- For lines that are not /foo/, neither /bar/, and neither eof : store the line in the array
@A
. After storing, go back for reading the next record provided not eof. - Only for the end of range, i.e.,
/bar/
oreof
, we take the action of printing what's in@A
and also emptying it, in preparation for the next gathering cycle.
add a comment |Â
up vote
2
down vote
You could do this way also:
a) This is POSIX-sed
compliant code wherein we store the mid-range lines (!/foo/ and !/bar/) in the hold area.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!H;$!d;
s/.*//;x;s/^n//;y/n/ /
' input-file.txt
b) and with Perl
as shown
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Explanation:
- skip non-interesting lines or lines that fall out of range. A range is defined as beginning with a line containing
/foo/
and ending with/bar/
, both occurring on separate lines. - Once we are in the range, then perform separate actions based on what line we are in.
- For lines that are not /foo/, neither /bar/, and neither eof : store the line in the array
@A
. After storing, go back for reading the next record provided not eof. - Only for the end of range, i.e.,
/bar/
oreof
, we take the action of printing what's in@A
and also emptying it, in preparation for the next gathering cycle.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
You could do this way also:
a) This is POSIX-sed
compliant code wherein we store the mid-range lines (!/foo/ and !/bar/) in the hold area.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!H;$!d;
s/.*//;x;s/^n//;y/n/ /
' input-file.txt
b) and with Perl
as shown
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Explanation:
- skip non-interesting lines or lines that fall out of range. A range is defined as beginning with a line containing
/foo/
and ending with/bar/
, both occurring on separate lines. - Once we are in the range, then perform separate actions based on what line we are in.
- For lines that are not /foo/, neither /bar/, and neither eof : store the line in the array
@A
. After storing, go back for reading the next record provided not eof. - Only for the end of range, i.e.,
/bar/
oreof
, we take the action of printing what's in@A
and also emptying it, in preparation for the next gathering cycle.
You could do this way also:
a) This is POSIX-sed
compliant code wherein we store the mid-range lines (!/foo/ and !/bar/) in the hold area.
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!H;$!d;
s/.*//;x;s/^n//;y/n/ /
' input-file.txt
b) and with Perl
as shown
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
Explanation:
- skip non-interesting lines or lines that fall out of range. A range is defined as beginning with a line containing
/foo/
and ending with/bar/
, both occurring on separate lines. - Once we are in the range, then perform separate actions based on what line we are in.
- For lines that are not /foo/, neither /bar/, and neither eof : store the line in the array
@A
. After storing, go back for reading the next record provided not eof. - Only for the end of range, i.e.,
/bar/
oreof
, we take the action of printing what's in@A
and also emptying it, in preparation for the next gathering cycle.
edited Sep 18 at 13:47
answered Sep 17 at 8:26
Rakesh Sharma
64513
64513
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f469458%2fdelete-newline-characters-between-patterns%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password