2

I'm trying to convert file wich could have one or more lines and extract word "three". Sample file is oneliner:

[test@test tmp]$ cat test1
onetwothreefourfive[pi@pidora tmp]$

I could make it in this way:

[test@test tmp]$ sed -e 's/.*two\(.*\)four.*/\1/' test1
three[pi@pidora tmp]$

But I have to make sure that my file is oneliner, so I'm using command from this question: How can I replace a newline (\n) using sed?

[test@test tmp]$ sed -e ':a;N;$!ba;s/\n/ /g' -e 's/.*two\(.*\)four.*/\1/' test1
onetwothreefourfive[pi@pidora tmp]$

It doesn't work.

[test@test tmp]$ sed -e ':a;N;$!ba;s/\n/ /g' test1| sed -e 's/.*two\(.*\)four.*/\1/'
three[test@test tmp]$

I use pipe and it works. Please explain to me why sed works wrong without pipe.

Thanks!

Community
  • 1
  • 1
user3461823
  • 1,303
  • 2
  • 11
  • 17
  • Note that your file is a zero-liner; it doesn't end with a newline. That will cause potential conniptions. – Jonathan Leffler Sep 14 '15 at 19:19
  • This doesn't really make any sense to go through all this complexity. Why don't you just check if "three" is in the file. If it is, then output it. – TomNash Sep 14 '15 at 19:23
  • What are you really trying to do? Are you looking for `three`, or are you looking for the characters that appear between `two` and `four`? What do you want if there are no characters between `two` and `four`? – Jonathan Leffler Sep 14 '15 at 19:23
  • Hi mates. I know that I could in simple way get this word "three". But it is only example. In original file is much more complicated (regexp and so on). I've simplified it. – user3461823 Sep 14 '15 at 19:48
  • Read [here](http://www.gnu.org/software/sed/manual/sed.html#Execution-Cycle) for the execution cycle of a sed program (especially the third paragraph). – potong Sep 14 '15 at 21:21

2 Answers2

1

Replace N by $!N or use a brackets:

sed ':a;$!{N;ba;};s/\n/ /g;s/.*two\(.*\)four.*/\1/' test1

Answer to your next question: I don't know why it works.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • Hi Cyrus. Good solution! It works both on one and multiline file and I will use it :-) I wish that you do not know the answer on the next question. I'm trying to understand how sed works... – user3461823 Sep 14 '15 at 21:04
  • 1
    I could be wrong but maybe it works because in my command I append new line at first (which doesn't exist), then check if this is last line. In yours: check first then append. If there is last line nothing to do... I accept th answer. Thanks Cyrus :-) – user3461823 Sep 16 '15 at 20:40
0

when you run one sed command with two manipulations, they are both being executed on the original text, so your second manipulations does not 'see' the \n added by the first one.

When you run it with the pipe, the second command is executed on the output from the first one, so the second command 'sees' the \n's

Nir Levy
  • 12,750
  • 3
  • 21
  • 38
  • Hi Nir, I tried following command - echo "onetwothree" | sed -e 's/two/xxx/' -e 's/xxx/yyy/' . The result is "oneyyythree" I conclude that every manipulation works on output from previous. Am I wrong? – user3461823 Sep 14 '15 at 20:53
  • right, each manipulation work on content given by previous one and this one line at a time (sed take 1 line, treat it than go to the next by default). Using buffer you can load several lines and treat the whole, in this case there are some new line between lines (and not if only1 line is loaded in working buffer). – NeronLeVelu Sep 15 '15 at 05:30