Bash - how to preserve newline in sed command outp

2020-04-07 03:11发布

Assuming I have a file BookDB.txt which stores data in the following format :

Harry Potter - The Half Blood Prince:J.K Rowling:40.30:10:50
The little Red Riding Hood:Dan Lin:40.80:20:10
Harry Potter - The Phoniex:J.K Rowling:50.00:30:20
Harry Potter - The Deathly Hollow:Dan Lin:55.00:33:790
Little Prince:The Prince:15.00:188:9
Lord of The Ring:Johnny Dept:56.80:100:38
Three Little Pig:Andrew Lim:89.10:290:189
All About Linux:Ubuntu Team:76.00:44:144
Catch Me If You Can:Mary Ann:23.60:6:2
Python for dummies:Jared Loo:15.99:1:10

I am trying to replace the (:) delimiter with (, ) in my output. It succeeds, but removes the newline from the output. Here is my code :

TITLE=Potter
OUTPUT=$(cat BookDB.txt | grep $TITLE)
OUTPUT1=$(sed 's/:/, /g' <<< $OUTPUT)
echo $OUTPUT1

I want my output to look like this :

Harry Potter - The Half Blood Prince, J.K Rowling, 40.30, 10, 50
Harry Potter - The Phoniex, J.K Rowling. 50.00. 30. 20
Harry Potter - The Deathly Hollow, Dan Lin, 55.00, 33, 790

However, it looks like this :

 Harry Potter - The Half Blood Prince, J.K Rowling, 40.30, 10, 50 Harry Potter - The Phoniex, J.K Rowling, 50.00, 30, 20 Harry Potter - The Deathly Holl
ow, Dan Lin, 55.00, 33, 790

If anyone could share how to preserve the line break in the output, I would be very grateful!

3条回答
Melony?
2楼-- · 2020-04-07 03:26

Using awk. Matching would be specific to the titles and doesn't include the author's name.

awk -F: -v OFS=', ' '$1 ~ /Potter/ { $1 = $1; print }' file

Output:

Harry Potter - The Half Blood Prince, J.K Rowling, 40.30, 10, 50
Harry Potter - The Phoniex, J.K Rowling, 50.00, 30, 20
Harry Potter - The Deathly Hollow, Dan Lin, 55.00, 33, 790

This gives no output:

awk -F: -v OFS=', ' '$1 ~ /Rowling/ { $1 = $1; print }' file

But this will:

awk -F: -v OFS=', ' '$2 ~ /Rowling/ { $1 = $1; print }' file

Output:

Harry Potter - The Half Blood Prince, J.K Rowling, 40.30, 10, 50
Harry Potter - The Phoniex, J.K Rowling, 50.00, 30, 20

To match against both title and author you can have:

awk -F: -v OFS=', ' '$1 ~ /Potter/ && $2 ~ /Rowling/ { $1 = $1; print }' file

Or to match if any validates:

awk -F: -v OFS=', ' '$1 ~ /Potter/, $2 ~ /Rowling/ { $1 = $1; print }' file
查看更多
女痞
3楼-- · 2020-04-07 03:38

Just use correct quotation :

TITLE=Potter
OUTPUT=$(cat BookDB.txt | grep $TITLE)
OUTPUT1=$(sed 's/:/, /g' <<< "$OUTPUT")
echo "$OUTPUT1"

As \n is part of the default value of IFS, it is removed without the double quotes.

More info on quoting here

查看更多
再贱就再见
4楼-- · 2020-04-07 03:42

You can avoid cat and do all in sed:

sed -n '/Potter/s/:/, /gp' file
Harry Potter - The Half Blood Prince, J.K Rowling, 40.30, 10, 50
Harry Potter - The Phoniex, J.K Rowling, 50.00, 30, 20
Harry Potter - The Deathly Hollow, Dan Lin, 55.00, 33, 790
查看更多
登录 后发表回答