2

The following code provides a backwards output when inputted as first to last, so input is required to be in reverse. How can this be flipped/reversed?

EDITED on 2019-05-23_07:52:04

(printf 'g?%s?m0\n' 0005 0004 0003 0002 0001 ; printf 'wq\n') | ed -s file.txt

However, I would like to do:

(printf 'g?%s?m0\n' 0001 0002 0003 0004 0005 ; printf 'wq\n') | ed -s file.txt

and get output order at the top of file.txt like this:

0001
0002
0003
0004
0005

file.txt is a playlist for ffmpeg and the zero padded numbers above are some chosen filenames of videos. The playlist has a bunch of filenames/videos already in it and I'd like to move a few to the top before compiling. However, not be required to input them in reverse order like the printf command requires if first to last ordering is desired.

UPDATED on 2019-05-23_07:54:27

$ cat file.txt
5575
3585
0004
7774
0003
5385
0001
8658
0002
0005

$ (printf 'g?%s?m0\n' 0001 0002 0003 0004 0005 ; printf 'wq\n') | ed -s file.txt

$ cat file.txt
0005
0004
0003
0002
0001
9374
4845
4834
4883
5848

Take note of the last cat command and the ordering of the output.

5
  • 1
    do you just want to reverse de line order? Why not use tac? Commented May 23, 2019 at 13:07
  • Yes!! EXACTLY!! How can I achieve that? And could you do the same with this one which is similar? This outputs to bottom of file rather than top of file. ( printf 'g?%s?m$\n' $3 | tac; echo 'wq'; ) | ed -s file.txt
    – Anonymous
    Commented May 23, 2019 at 13:21
  • 3
    @AnonymousUser it might be worth re-stating your goal with another example - based on your recent post history, you seem to be in "every problem is a nail" mode Commented May 23, 2019 at 13:26
  • @steeldriver Ohh. I'm not surprised you say that. How can I improve/change?
    – Anonymous
    Commented May 23, 2019 at 15:11
  • 1
    tail -r reverses the line order of its input.
    – Jim L.
    Commented May 24, 2019 at 0:02

3 Answers 3

4

Even though my suggestion with tac worked, I think that maybe, your are making this much harder than it is.

If you have file.txt, and you simply want to add some lines at the beginning of file.txt, say, lines you have in a header_file.txt, you can simply do this:

cat header_file.txt file.txt > new_playlist.txt

and done.

5
  • How does this reverse the order of the output from the first printf command? I thought > was to append additions to the file?
    – Anonymous
    Commented May 23, 2019 at 14:11
  • this doesn't revert the order of the output of printf... it was simply that, at the beginning, it was not clear at all what you were trying to do, so, one tries to help you in the best possible way with the information you provided. Commented May 23, 2019 at 14:15
  • I am terribly sorry if I offended. I don't see how I am making things harder than they are though. I have updated my question so that you can understand much better what it is I am asking. If you are giving your full positive effort in reading my question then I greatly appreciate your time.
    – Anonymous
    Commented May 23, 2019 at 15:08
  • 1
    there is no offense, and yeah, it's much clearer now. I'm glad that you solved your problem. Commented May 23, 2019 at 16:01
  • Cool cool man :)
    – Anonymous
    Commented May 23, 2019 at 16:55
3
( printf 'g?%s?m0\n' 0005 0004 0003 0002 0001 | tac ; printf 'wq\n' ) | ed -s file.txt

This reverses the ed commands produced by the first printf.

5
  • 1
    "This reverses the ed commands produced by the first printf." See, this guy knows what I asked. This is the answer that needs upvoting ...
    – Anonymous
    Commented May 23, 2019 at 14:14
  • 1
    Hey can you do the same for ( printf 'g?%s?m$\n' 0001 0002 0003 | tac ; printf 'wq\n' ) | ed -s file.txt This one puts the numbers to the bottom of the file rather than at the top. The difference in code is to the right of the m as its a $ instead of a 0 However, the ordering is reversed and as you know I want it first to last OR top to bottom.
    – Anonymous
    Commented May 23, 2019 at 16:54
  • @AnonymousUser Remove the | tac.
    – Kusalananda
    Commented May 23, 2019 at 16:58
  • Hey I tried removing tac and it did nothing, like no results, no change to the file. Here is the code I executed: ( printf 'g?%s?m$\n' 0001 0002 0003 | printf 'wq\n' ) | ed -s file.txt any ideas?
    – Anonymous
    Commented May 23, 2019 at 23:54
  • Hey my man! I got it! { printf 'g?%s?m$\n' $3; echo 'wq'; } | ed -s $VIDEO_LIST; Thank you again for your much appreciated intelligence and being so kind in sharing with me. See you! :)
    – Anonymous
    Commented May 24, 2019 at 0:01
2

Instead of moving lines on-by-one to the top, you could move the one-by-one to the bottom (which preserves the desired order) and then move them as a group to the top. Taking it a step at a time:

  1. Insert a placeholder line (whose contents could be anything - the simplest is just an empty line) and then move the selected lines to the end of the file m$. (NOTE: I changed the g?...? reverse search to more conventional g/.../ - it doesn't actually matter which direction you search in.)

    $ { printf '$a\n\n.\n'; printf 'g/%s/m$\n' 0001 0002 0003 0004 0005; printf ',p\nq\n'; } | ed -s file.txt
    5575
    3585
    7774
    5385
    8658
    
    0001
    0002
    0003
    0004
    0005
    
  2. Now add a mark (kx) on the placeholder line, so that we can address lines x to $ and move them to the top using 'x,$m0:

    $ { printf '$a\n\n.\nkx\n'; printf 'g/%s/m$\n' 0001 0002 0003 0004 0005; printf \''x,$m0\n,p\nq\n'; } | ed -s file.txt
    
    0001
    0002
    0003
    0004
    0005
    5575
    3585
    7774
    5385
    8658
    
  3. Finally we need to remove the placeholder (which is now line 1):

    $ { printf '$a\n\n.\nkx\n'; printf 'g/%s/m$\n' 0001 0002 0003 0004 0005; printf \''x,$m0\n1d\n,p\nq\n'; } | ed -s file.txt
    0001
    0002
    0003
    0004
    0005
    5575
    3585
    7774
    5385
    8658
    

Putting it all together and replacing ,p by wq to edit in place:

$ cat file.txt
5575
3585
0004
7774
0003
5385
0001
8658
0002
0005
$
$ { printf '$a\n\n.\nkx\n'; printf 'g/%s/m$\n' 0001 0002 0003 0004 0005; printf \''x,$m0\n1d\n,wq\n'; } | ed -s file.txt
$
$ cat file.txt
0001
0002
0003
0004
0005
5575
3585
7774
5385
8658
3
  • Now to make it all a one-liner, haha.
    – Anonymous
    Commented May 23, 2019 at 16:09
  • @AnonymousUser it is ... Commented May 23, 2019 at 16:11
  • ... and even if it wasn't already a one-liner, that's what shell functions are for.
    – Kusalananda
    Commented May 23, 2019 at 16:12

You must log in to answer this question.

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