1

I am trying to figure out how to break a string to be on character per line.
I.e ahebhaaa to be:

a  
h  
e  
b  
h  
a  
a  
a  

I tried:

$ echo ahebhaaa | sed 's/\(.\)\(.\)/\1\n\2/g'
I.e. my intention was "plugin" between chars a new line using capture groups but I get:

a  
he  
bh  
aa  
a   

I guess this has to do with greedy/non-greedy but adding ?* anywhere in this does not do anything. What am I doing wrong here?

Additionally I found that this:
echo ahebhaaa | sed 's/[^\n]/&\n/g'
Does the job. But I don't understand how it works. What is &? How does the [^\n] work?

4

capture groups

Your first example was close, but you're telling sed that you want to take 2 characters at a time with the \(.\)\(.\) bit, to do it using a capture group you could adjust it like so:

$ echo ahebhaaa | sed 's/\(.\)/\1\n/g'
a
h
e
b
h
a
a
a

using &

As to why the sed example with the & works. The & in a search and replace is what ever characters the regular expression matched. So everything that was not a \n.

Examples

$ echo "123 abc" | sed 's/[0-9]*/&&/'
123123 abc

The first & prints the characters that were matched by the pattern ([0-9]*), 123. The second & prints them a second time.

$ echo "123 abc" | sed 's/ab/&&&/'
123 abababc

The pattern we're looking for is ab. As we walk the string 123 abc sed is printing the non-matched characters, 123. Then the string ab is encountered which at that point matches what we're searching and replacing on. So sed then replaces it with 3 copies of what matched (abbab). Finally sed prints the c.

The notation [^\n] creates a set of not a end of line character. So think of sed as it's walking along your string of text, ahebhaaa, it's testing each of these characters and saying "Is this not a \n"? If it's not a end of line character, then sed does a search and replace on this character and the & prints what was matched, i.e. the character, along with a new line character. It then repeats this as it walks along the ahebhaaa string.

References

  • Great explanation!The & is it part of the standard regex?I don't remember using it ever before – Jim Sep 15 '13 at 10:24
  • @Jim - yeah it's a standard part, I haven't seen it used myself that much either. I'll add a reference if you want to read up on it a bit more. – slm Sep 15 '13 at 10:26
  • @Jim - see updates. – slm Sep 15 '13 at 10:30
2

I don't understand why the \n comes into play in that example, since it is a single line pattern space situation, so there are no newlines. Therefore this should suffice:

sed 's/./&\n/g'
2

An alternative in Perl

echo "abcdefg"|perl -nle 'print for split//'
  • +1:Can not figure out how to run perl one-liners from a bash like that – Jim Sep 15 '13 at 16:10
  • 1
    @Jim man perlrun will help you with the usage of switches. "Magic" one-liners like the above make heavy use of Perl's special variables. The above statement, when made explicit, reads print $_ foreach $_ (split //,$_) See man perlvar for more on special variables. – Joseph R. Sep 15 '13 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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