Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I split a word's letters, with each letter in a separate line?

For example, given "StackOver" I would like to see

S
t
a
c
k
O
v
e
r

I'm new to bash so I have no clue where to start.

share|improve this question

12 Answers 12

up vote 27 down vote accepted

I would use grep:

$ grep -o . <<<"StackOver"
S
t
a
c
k
O
v
e
r

or sed:

$ sed 's/./&\n/g' <<<"StackOver"
S
t
a
c
k
O
v
e
r

And if empty space at the end is an issue:

sed 's/\B/&\n/g' <<<"StackOver"

All of that assuming GNU/Linux.

share|improve this answer
    
grep -o . <<< ¿¿¿ .. -o searches for the PATTERN provided right? and what it does here in your command? – Sijaan Hallak Jan 5 at 0:06
1  
@jimmij I cant find any help on what <<< really does! any help? – Sijaan Hallak Jan 5 at 10:50
3  
@SijaanHallak This is so called Here string, grosso modo equivalent of echo foo | ... just less typing. See tldp.org/LDP/abs/html/x17837.html – jimmij Jan 5 at 11:02
1  
@SijaanHallak change . to \B (doesn't match on word boundary). – jimmij Jan 5 at 17:40
1  
@SijaanHallak - you can drop the second sed like: sed -et -e's/./\n&/g;//D' – mikeserv Jan 6 at 6:30

You may want to break on graphem clusters instead of characters if the intent is to print text vertically. For instance with a e with an acute accent:

  • With graphem clusters (e with its acute accent would be one graphem cluster):

    $ perl -CLAS -le 'for (@ARGV) {print for /\X/g}' $'Ste\u301phane'
    S
    t
    é
    p
    h
    a
    n
    e
    

    (or grep -Po '\X' with GNU grep built with PCRE support)

  • With characters (here with GNU grep):

    $ printf '%s\n' $'Ste\u301phane' | grep -o .
    S
    t
    e
    
    p
    h
    a
    n
    e
    
  • fold is meant to break on characters, but GNU fold doesn't support multi-byte characters, so it breaks on bytes instead:

    $ printf '%s\n' $'Ste\u301phane' | fold -w 1
    S
    t
    e
    �
    �
    p
    h
    a
    n
    e
    

On StackOver which only consists of ASCII characters (so one byte per character, one character per cluster), all three would give the same result.

share|improve this answer
    
I'm surprised grep -Po doesn't do what one would expect (like grep -P does). – jimmij Jan 5 at 0:19
    
@jimmij, what do you mean? grep -Po . finds characters (and a combining acute accent following a newline character is invalid), and grep -Po '\X' finds graphem clusters for me. You may need a recent version of grep and/or PCRE for it to work properly (or try grep -Po '(*UTF8)\X') – Stéphane Chazelas Jan 5 at 0:23
2  
@SijaanHallak These might be helpful: joelonsoftware.com/articles/Unicode.html, eev.ee/blog/2015/09/12/dark-corners-of-unicode – jpmc26 Jan 5 at 21:55

If you have perl6 in your box:

$ perl6 -e 'for @*ARGS -> $w { .say for $w.comb }' 'cường'       
c
ư
ờ
n
g

work regardless of your locale.

share|improve this answer

With many awk versions

awk -F '' -v OFS='\n' '{$1=$1};1' <<<'StackOver'
share|improve this answer

You can handle multibyte characters like:

<input \
dd cbs=1 obs=2 conv=unblock |
sed -e:c -e '/^.*$/!N;s/\n//;tc'

Which can be pretty handy when you're working with live input because there's no buffering there and a character is printed as soon it is whole.

share|improve this answer
    
NP, should we add a note about the locale? – cuonglm Jan 5 at 9:35
    
Does not work for combining characters like Stéphane Chazelas answer, but with proper normalization this should not matter. – Kay Jan 5 at 13:06
    
@Kay - it's works for combining characters if you want it to - that's what sed scripts are for. i'm not likely to write one right about now - im pretty sleepy. it's really useful, though, when reading a terminal. – mikeserv Jan 5 at 14:30
    
@cuonglm - if you like. it should just work for the locale, given a sane libc, though. – mikeserv Jan 5 at 14:33
    
Note that dd will break multibyte characters, so the output will not be text anymore so the behaviour of sed will be unspecified as per POSIX. – Stéphane Chazelas Jan 5 at 22:09

Also Python 2 can be used from the command line:

python <<< "for x in 'StackOver':
   print x"

or:

echo "for x in 'StackOver':
    print x" | python

or (as commented by 1_CR) with Python 3:

python3 -c "print(*'StackOver',sep='\n')"
share|improve this answer

The below will be generic:

$ awk -F '' \
   'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>
share|improve this answer

You may use word boundaries also..

$ perl -pe 's/(?<=.)(\B|\b)(?=.)/\n/g' <<< "StackOver"
S
t
a
c
k
O
v
e
r
share|improve this answer

Since you specifically asked for an answer in bash, here's a way to do it in pure bash:

while read -rn1; do echo "$REPLY" ; done <<< "StackOver"

Note that this will catch the newline at the end of the "here document". If you want to avoid that, but still iterate over the characters with a bash loop, use printf to avoid the newline.

printf StackOver | while read -rn1; do echo "$REPLY" ; done
share|improve this answer

You can use the fold (1) command. It is more efficient than grep and sed.

$ time grep -o . <bigfile >/dev/null

real    0m3.868s
user    0m3.784s
sys     0m0.056s
$ time fold -b1 <bigfile >/dev/null

real    0m0.555s
user    0m0.528s
sys     0m0.016s
$

One significant difference is that fold will reproduce empty lines in the output:

$ grep -o . <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$ fold -b1 <(printf "A\nB\n\nC\n\n\nD\n")
A
B

C


D
$ 
share|improve this answer
echo StackOver | sed -e 's/./&\n/g'
S
t
a
c
k
O
v
e
r
share|improve this answer
    
This won't help as it prints a new line at the end – Sijaan Hallak Jan 5 at 10:56
$  echo stackover | fold -w1
s
t
a
c
k
o
v
e
r
share|improve this answer
    
Will this ever give different results to fold -b1 ? – JigglyNaga 2 days ago
    
since each byte have a width=1 the result will be the same ! – younes 2 days ago
    
So how is this not a duplicate of the earlier answer? – JigglyNaga 2 days ago
    
because it shows tha same cmd with different argyment , and that is nice to know . – younes 2 days ago

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.