Reputation: 702
Essentially, I want to read a file and concatenate each line to the next line, only if the first line has a length of less than 6. (Six is the maximum length of a chapter "number".)
16.
Chapter Name
17.
Chapter Name
Appendix
A.1.
Appendix name
A.2.
Appendix name
In this example the output would be:
16. Chapter name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
Using this:
sed 'N;s/\n/ /'
results in:
16. Chapter Name
17. Chapter Name
Appendix A.1.
Appendix name A.2.
Appendix name
Does sed support the use of logic to move a line to the hold buffer based on its length (or if it fits a pattern)?
Would awk be a better option?
Upvotes: 0
Views: 211
Reputation: 1517
awk 'sub(/\.$/,". "){printf $0;next}1' file
16. Chapter Name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
Upvotes: 0
Reputation: 23667
Another sed
solution
$ sed -E '/^.{,5}$/{N; s/\n/ /}' ip.txt
16. Chapter Name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
/^.{,5}$/
if line has maximum of 5 characters
N;
get next lines/\n/ /
substitute the first \n
with spacesed
versions use -r
instead of -E
for extended regex
And another perl
solution
$ perl -lpe '$_ .= " ".<> if length() < 6; chomp' ip.txt
16. Chapter Name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
$_
contains the current line$_ .= " ".<> if length() < 6
append space and next line if current line is less than 6 characterschomp
remove ending new line character if present from $_
. Required because the next line obtained by <>
would have \n
character-l
option removes ending \n
from input lines and adds it back while printing-p
iterate over input files in a loop, $_
value is printed by default at end of all commandsUpvotes: 1
Reputation: 3451
If Perl is an option:
perl -pe 'chomp; $_.=(length()<6?" ":"\n")' file
chomp
removes the newline
$_
is the current line
The ternary ?
:
operator either appends a space or a newline
Upvotes: 0
Reputation: 52142
With sed:
$ sed -r 'N;/^(.){,5}\n/s/\n/ /;P;D' infile
16. Chapter Name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
-r
) are just used so I didn't have to type \(.\)\{,5\}
.N;P;D
creates a moving two-line window: N
appends the next line to the pattern space, P
prints the first line of the pattern space, and D
deletes it./^(.){,5}\n/
matches if the pattern space contains five or fewer characters before the newlines/\n/ /
concatenates the two linesThe hold space isn't required for this, but if it were, you could copy the pattern space based on its length with the same regex as used here.
Upvotes: 1
Reputation: 37404
In awk:
$ awk '{printf "%s", $0 (length($0)<6?" ":ORS)}' foo
16. Chapter Name
17. Chapter Name
Appendix
A.1. Appendix name
A.2. Appendix name
Upvotes: 1