Bubnoff
Bubnoff

Reputation: 4097

sed: truncate long entry across multiple lines

First, I have what I believe to be a workable solution. However, test cases are one thing ...reality is not always so kind. This is a "Does this look right?" question ...or, better, "Where might this fail? Suggest improvements?" question.

Problem:
Title should not creep past one line.

Test file:

You have a hold available for pickup as of 2012-01-13:
Title: Really Long Test Title Regarding Random Gibberish. Volume 1, A-B, United States
 and affiliated territories, United Nations, countries of the world
Author: Barrel Roll Morton
Copy: 3
#end-of-record
You have a hold available for pickup as of 2012-01-13:
Title: Short Catalogue of Random Gibberish. Volume 1, A-B, United States
Author: Skippy Credenza
Copy: 12
#end-of-record

Expected output:

You have a hold available for pickup as of 2012-01-13:
Title: Really Long Test Title Regarding Random Gibberish. Volume 1, A-B, United States
Author: Barrel Roll Morton
Copy: 3
#end-of-record
You have a hold available for pickup as of 2012-01-13:
Title: Short Catalogue of Random Gibberish. Volume 1, A-B, United States
Author: Skippy Credenza
Copy: 12
#end-of-record

My solution:

sed -e '/^Title/{N;/\nAuthor:/!{s/\n.*$//}}' test-file.txt

My logic re: above proposed solution

Is there a more bullet proof way to do this?

Upvotes: 2

Views: 408

Answers (4)

shellter
shellter

Reputation: 37258

That looks good, but if you don't have control on how long that first line of text is, you can further truncate it using something like

sed '/^Title/{N;/\nAuthor:/!{s/^\(....................\).*\n.*$/\1/;};}' test-file.txt

(You don't need the -e, but it doesn't hurt either).

I use an old-school sed, so I need the ;};} extra-bits.

Adjust the number of '.'s in the match-pattern for the length of value you want to capture.

Newer sed support curly-braced ranges, something like, cut I don't have access to confirm.

sed '/^Title/{N;/\nAuthor:/!{s/^\(.\{30,50\}\).*\n.*$/\1/;};}' test-file.txt

Edit per @JonathanLeffler 's comment below. fixed range notation, change 30,50 to values that work for you.

I hope this helps.

Upvotes: 2

jaypal singh
jaypal singh

Reputation: 77075

If you are fine with awk then you can do something like this -

awk '/Title:/{print $0; getline; while ($0!~/Author:/) {getline}}1' file

Upvotes: 1

SiegeX
SiegeX

Reputation: 140227

Although not exactly what you asked for (potong's solution seems the best for that), the following will append an N-line title into a single line rather than truncate it.

sed '/^Title:/{:a;N;/\nAuthor:/!s/\n//;ta;P;D}' test-file.txt

Output

$ sed '/^Title:/{:a;N;/\nAuthor:/!s/\n//;ta;P;D}' test-file.txt
You have a hold available for pickup as of 2012-01-13:
Title: Really Long Test Title Regarding Random Gibberish. Volume 1, A-B, United States and affiliated territories, United Nations, countries of the world.  Also, this title is a whole three lines in length
Author: Barrel Roll Morton
Copy: 3
#end-of-record
You have a hold available for pickup as of 2012-01-13:
Title: Short Catalogue of Random Gibberish. Volume 1, A-B, United States
Author: Skippy Credenza
Copy: 12
#end-of-record

Upvotes: 1

potong
potong

Reputation: 58351

This might work for you:

sed '/^Title/,/^Author/{//!d}' file

If you wish to truncate the Title line, then

sed '/^Title/,/^Author/{//!d;s/^\(Title.\{25\}\).*/\1/}' file

This reduces the Title to 30 characters in length.

Upvotes: 2

Related Questions