11

I am doing grep and sed and I get 2 lines of a file that I am interested in. How can I get these lines in a single line ending with the new line character?
Now I am getting:

pattern1  
pattern2  

I would like to get pattern1 pattern2 \n

4
  • 1
    Can you share more of the sample data?
    – slm
    Commented Aug 22, 2014 at 14:27
  • Use printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /' Commented Aug 22, 2014 at 14:35
  • Paste is the tool for the job, if you're intending to merge multiple lines of output into one.
    – slm
    Commented Aug 22, 2014 at 16:10
  • any specific tool? How do you plan to do this?
    – Braiam
    Commented Aug 23, 2014 at 3:31

7 Answers 7

8

paste:

{...pipeline...} | paste -d " " - -

That says: "read a line from stdin (the first -), read another line from stdin (the second -), then join them with a space"


a bash-specific technique:

$ x=$(grep -o pattern. test.txt)
$ echo "$x"
pattern1
pattern2
$ mapfile -t <<< "$x"
$ echo "${MAPFILE[*]}"
pattern1 pattern2

ref: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile

2
  • What is - -? Is the command like that?
    – Jim
    Commented Aug 22, 2014 at 14:28
  • @Jim - yes that's correct. Those are telling paste how you want it to process the input. 2 at a time. Add more to do 3 at at time. seq 10 | paste -d " " - - .
    – slm
    Commented Aug 22, 2014 at 16:08
6

I'll put three versions different methods in a row

AWK

printf %s\\n pattern1 pattern2 | awk -vRS="\n" -vORS=" " '1; END {print RS}'

SED

printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'

TR

printf %s\\n pattern1 pattern2 | tr '\n' ' '; echo

And there are many more.

2
  • The tr solution will swallow the ending newline, so you might want to add ; echo to that one Commented Aug 22, 2014 at 15:12
  • @glennjackman ah right! Thanks for the hint. You are free to modify the answer though. I missed that bit! Commented Aug 22, 2014 at 15:19
2

you can do it using shell script or in command-line, just put the output of the command in a variable then echo it:

# x=$(grep -e "pattern1\|pattern2" test)
# printf '%s\n' "$x"
pattern1 pattern2
4
  • unquoted, the variable is also subject to filename expansion, so if you have any glob characters (like * or ?) in the result, the values may change. Commented Aug 22, 2014 at 14:38
  • @glennjackman, thanks for mention this, how can we fix this?
    – Nidal
    Commented Aug 22, 2014 at 14:40
  • @Networker by not using backticks but $() instead.. and using printf printf '%s\n' "$x" Commented Aug 22, 2014 at 14:41
  • I would expect that printf '%s\n' "$x" will NOT remove the "internal" newline. Commented Aug 22, 2014 at 14:50
2

With sed, you can do this:

<your previous commands> | sed '{N; s/\n/ /}'
  • N; tells sed to add the next line into the pattern space, so now sed is working with both lines.
  • s/\n/ / replaces the newline character with a space, "merging" the two lines together.
2

A simple way, pipe output to xargs:

$ echo -e 'a\nb' | xargs
a b

This only works with small ouput, because it's limited by maximum characters per command line. The largest value depends on system, you can get this value using getconf ARG_MAX.

1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS will be happy to eat it if you want.

-1

wrap your sed/grep in backticks

when your original command was:

grep -i 'foo' mylog.log | sed 's/bar/baz/gi'

your new command would be:

`grep -i 'foo' mylog.log | sed 's/bar/baz/gi'`

Doesn't get the spaces in between lines, but you can always tack on another sed pipe:

 | sed 's/$/ /'
1
  • 1
    Uh, no. That will execute the output of the sed command. Commented Aug 23, 2014 at 0:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .