2

I have a command which outputs in this format:

A
B
C
D
E
F
G
I
J

etc I want the output to be in this format

A B C D E F G I J

I tried using ./script | tr "\n" " " but all it does is remove n from the output How do I get all the output in one line.

Edit: I accidentally put in grep while asking the question. I removed it. My original question still stands.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214

4 Answers4

4

The grep is superfluous.

This should work:

./script | tr '\n' ' '

It did for me with a command al that lists its arguments one per line:

$ al A B C D E F G H I J
A
B
C
D
E
F
G
H
I
J
$ al A B C D E F G H I J | tr '\n' ' '
A B C D E F G H I J $
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • `tr "\n" " "` should work. The OP's original command wasn't even invoking `tr`. – Keith Thompson Jul 05 '12 at 05:31
  • @KeithThompson: Yes, I've removed the extra comment. `bash` at least seems to convert `\n` inside double quotes into an actual newline. (I'm pretty sure that Bourne shell never did that.) Indeed, `bash` seems to do that inside single quotes (which strikes me as very dubious; the contents of single quotes are supposed to be inviolate, from one single quote to the next. If that changes, there's no way to be sure that you get what (die-hard Bourne-shell programmers) expect. – Jonathan Leffler Jul 05 '12 at 05:34
  • 1
    No, but the `tr` command translates the backslash-n sequence into a newline. – Keith Thompson Jul 05 '12 at 05:35
  • For ls -al the tr '\n' ' ' works. I am using redis command which lists all the attributes vertically. But when I use | tr '\n' ' ' it outputs a blank line –  Jul 05 '12 at 05:37
  • 1
    Does `redis` generate CRLF line endings? – Jonathan Leffler Jul 05 '12 at 05:44
  • @JonathanLeffler it has carriage returns. So, I changed it to | tr '\n\r' ' ' and it works now –  Jul 05 '12 at 05:49
  • @Jonathan Leffler: using double quotes invokes shell interpolation, if you want a new-line (in the shell) use `$'\n'`. `tr(1)` also translates special characters, but you need single quotes to protect them from the shell. `echo '\n'` gives `\n`. – cdarke Jul 05 '12 at 08:36
2

As Jonathan Leffler points out, you don't want the grep. The command you're using:

./script | grep tr "\n" " "

doesn't even invoke the tr command; it should search for the pattern "tr" in files named "\n" and " ". Since that's not the output you reported, I suspect you've mistyped the command you're using.

You can do this:

./script | tr '\n' ' '

but (a) it joins all its input into a single line, and (b) it doesn't append a newline to the end of the line. Typically that means your shell prompt will be printed at the end of the line of output.

If you want everything on one line, you can do this:

./script | tr '\n' ' ' ; echo ''

Or, if you want the output wrapped to a reasonable width:

./script | fmt

The fmt command has a number of options to control things like the maximum line length; read its documentation (man fmt or info fmt) for details.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

No need to use other programs, why not use Bash to do the job? (-- added in edit)

line=$(./script.sh) 
set -- $line
echo "$*"

The set sets command-line options, and one of the (by default) seperators is a "\n". EDIT: This will overwrite any existing command-line arguments, but good coding practice would suggest that you reassigned these to named variables early in the script.

When we use "$*" (note the quotes) it joins them alll together again using the first character of IFS as the glue. By default that is a space.

tr is an unnecessary child process.

By the way, there is a command called script, so be careful of using that name.

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • The `set` is superfluous as well, and could overwrite script parameters. `echo "${line[*]}"` should work just as well. – chepner Jul 05 '12 at 13:14
  • wordsplit + pathname expansion + possible conflicts with `set` options without `--` most likely. Pretty good collection of all the issues with this over [here](http://mywiki.wooledge.org/Arguments) – ormaaj Jul 05 '12 at 13:18
  • You got me. I usually includde the `--` but I omitted them this time. `echo "${line[*]}"` would only work if `line` was an array. As it stands it is not, but it is easy to do with and extra set of parens: `line=($(./script.sh))`. I like that one. – cdarke Jul 06 '12 at 08:34
0

If I'm not mistaken, the echo command will automatically remove the newline chars when its argument is given unquoted:

tmp=$(./script.sh)
echo $tmp

results in

A B C D E F G H I J

whereas

tmp=$(./script.sh)
echo "$tmp"

results in

A 
B 
C 
D 
E 
F 
G 
H 
I 
J

If needed, you can re-assign the output of the echo command to another variable:

tmp=$(./script.sh)
tmp2=$(echo $tmp)

The $tmp2 variable will then contain no newlines.

Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96