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.

  • 1
    do you just want to reverse de line order? Why not use tac? – matsib.dev May 23 '19 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 May 23 '19 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 – steeldriver May 23 '19 at 13:26
  • @steeldriver Ohh. I'm not surprised you say that. How can I improve/change? – Anonymous May 23 '19 at 15:11
  • 1
    tail -r reverses the line order of its input. – Jim L. May 24 '19 at 0:02
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.

  • 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 May 23 '19 at 14:14
  • 1
    THANK YOU SO DAMN MUCH! – Anonymous May 23 '19 at 15:06
  • 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 May 23 '19 at 16:54
  • @AnonymousUser Remove the | tac. – Kusalananda May 23 '19 at 16:58
  • hehe, thank you! :) – Anonymous May 23 '19 at 17:04
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.

  • How does this reverse the order of the output from the first printf command? I thought > was to append additions to the file? – Anonymous May 23 '19 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. – matsib.dev May 23 '19 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 May 23 '19 at 15:08
  • 1
    there is no offense, and yeah, it's much clearer now. I'm glad that you solved your problem. – matsib.dev May 23 '19 at 16:01
  • Cool cool man :) – Anonymous May 23 '19 at 16:55
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
  • Now to make it all a one-liner, haha. – Anonymous May 23 '19 at 16:09
  • @AnonymousUser it is ... – steeldriver May 23 '19 at 16:11
  • ... and even if it wasn't already a one-liner, that's what shell functions are for. – Kusalananda May 23 '19 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.