Sadhun
Sadhun

Reputation: 264

Replacing space with newline at specified positions in a file

InputFile:

filed1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12

I need to replace only the spaces after field3,field6,field9 to a new line character. I tried the below sed command and it worked, But am looking for a more optimised solution for the same in order to handle input files with more fields.

sed -e 's/ /\
/3' -e 's/ /\
/6' -e 's/ /\
/9' InputFile

Thanks in advance.

Upvotes: 0

Views: 55

Answers (4)

potong
potong

Reputation: 58400

This might work for you (GNU sed):

sed 's/ /\n/3;P;D' file

This changes the third space to a newline then prints and deletes upto and including the newline and repeats the process till the line is consumed.

Upvotes: 0

Jotne
Jotne

Reputation: 41456

Here is an awk version:

awk '{for (i=1;i<=NF;i++) printf "%s%s",$i,(i%3?FS:RS)}' file
filed1 field2 field3
field4 field5 field6
field7 field8 field9
field10 field11 field12

PS this does not stop at 3,6,9 but goes on (12,15,18...)

for (i=1;i<=NF;i++) Loop trough the line by one and one field.
printf print data $i print current data. i%3?FS:RS if filed is number 3 use newline RS, else use field separator FS

Upvotes: 1

nu11p01n73R
nu11p01n73R

Reputation: 26667

using grep

 echo "filed1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12" | grep -oE '([^ ]+ *){3}'

will produce output as

filed1 field2 field3
field4 field5 field6
field7 field8 field9
field10 field11 field12

using sed

 echo "filed1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12" | sed -r  's/(([^ ]+ *){3})/\1\n/g'

will produce output as

filed1 field2 field3
field4 field5 field6
field7 field8 field9
field10 field11 field12

/(([^ ]+ *){3} matches anything another than space followed by space 3 times which effectivly selects selects 3 fields.

 echo "filed1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12" | awk  '{for(i=1;i<NF;i+=3) print $i, $(i+1), $(i+2)}'

will give output as

filed1 field2 field3
field4 field5 field6
field7 field8 field9
field10 field11 field12

Throgh basic sed,

$ echo "filed1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12" | sed 's/\(\([^ ]\+ \)\{3\}\)/\1\n/g'
filed1 field2 field3 
field4 field5 field6 
field7 field8 field9 
field10 field11 field12

Upvotes: 2

NeronLeVelu
NeronLeVelu

Reputation: 10039

sed 's/\(\([^ ]\{1,\} \{1,\}\)\{2\}\([^ ]\{1,\}\) \{1,\}/\1\
/g' YourFile

replace space after a group of 2 group of (non space + space) than 1 non space by a new line, and this repeated until it's possible on the line.

Posix version so --posix for GNU sed

sed 's/(([^ ]+ +){2}([^ ]+) +/\1\n/g' YourFile

should work on GNU sed (cannot test from here)

sed 's/\( *[^ ]*\)\{3\} */\1\
/g' YourFile

should also work on sed (depend on implementation)

Upvotes: 1

Related Questions