Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I have a file with Feature names and a variable number of usernames below:

Feature1

user1

user2

Feature2

user3

I'd like to be able to move the usernames to the same line as the Feature name (along the lines of the vi join command). The Feature names begin with an uppercase letter and the usernames begin with lowercase. Is there a way to do this?

share|improve this question

3 Answers 3

That's pretty easy with sed:

sed ':a;N;$!ba;s/\n\+\([a-z]\)/ \1/g;'

Small description how it works:

:a;N;$!ba; will add all lines into match pattern. we need it to delete all newlines in the next step. s/\n\+\([a-z]\)/ \1/g; will delete all newlines before user* and save newlines before Feature*. btw it also can be done with

tr '\n' ' ' | sed 's/ \([A-Z]\)/\n\1/g'


 $ cat test_file
Feature1

user1

user2
Feature2

user3
Feature2
user3
user3

ouser3

user3

 $ sed ':a;N;$!ba;s/\n\+\([a-z]\)/ \1/g;' test_file
Feature1 user1 user2
Feature2 user3
Feature2 user3 user3 ouser3 user3
share|improve this answer
    
Mind adding some discussion about what each step of the sed statement is doing? Sed is a powerful but hard to grok beast sometimes. –  Red Tux Jun 26 '12 at 22:09
    
I've added small description. Hope now it's a little bit clear. –  rush Jun 27 '12 at 5:15
1  
Heh. sed is one of the tools that makes some of my colleagues go "What kind of wizardry is this!!" mode. Nicely done, Rush! :) –  Janne Pikkarainen Jun 27 '12 at 5:28

It's very straightforward in AWK:

awk '/^[[:upper:]]/ {if (line) {print line}; line = $0} /^[[:lower:]]/ {line = line " " $0} END {if (line) {print line}}'
share|improve this answer

You will want to chunk your data before writing it. Something like the following pseudocode (you will need to make this into proper BASH syntax yourself).

out_line=""
for in_line in $(cat $file); do
  if $(echo in_line | egrep ^Feature) != ""
    echo $out_line >> $out_file
    out_line="$in_line"
  else
    out_line="$out_line $in_line"
  fi
done
echo $out_line >> $out_file
share|improve this answer
    
Thanks! That did it. –  user126071 Jun 26 '12 at 21:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.