Search code examples
stringshellaccumulator

Concating string with shell script with accumulator


I'd like to convert a list separated with '\n' in another one separated with space. Ex: Get a dictionary like ispell english dictionary. http://downloads.sourceforge.net/wordlist/ispell-enwl-3.1.20.zip

My initial idea was using a variable as accumulator:

a=""; cat american.0 | while read line; do a="$a $line"; done; echo $a

... but it results '\n' string!!!

Questions:

  1. Why is it not working?
  2. What is the correct way to do that?

    Thanks.


Solution

  • The problem is that when you have a pipeline:

    command_1 | command_2
    

    each command is run in a separate subshell, with a separate copy of the parent environment. So any variables that the command creates, or any modifications it makes to existing variables, will not be perceived by the containing shell.

    In your case, you don't really need the pipeline, because this:

    cat filename | command
    

    is equivalent, in every way that you need, to this:

    command < filename
    

    So you can write:

    a=""; while read line; do a="$a $line"; done < american.0; echo $a
    

    to avoid creating any subshells.

    That said, according to this StackOverflow answer, you can't really rely on a shell variable being able to hold more than about 1–4KB of data, so you probably need to rethink your overall approach. Storing the entire word-list in a shell variable likely won't work, and even if it does, it likely won't work well.


    Edited to add: To create a temporary file named /tmp/american.tmp that contains what the variable $a would have, you can write:

    while IFS= read -r line; do
      printf %s " $line"
    done < american.0 > /tmp/american.tmp