0

Code below can, for example ...

[anony@mous-pc ~]$ (printf 'g?%s?m0\n' 008 006 004 002 ; printf 'wq\n') | ed -s file.txt

... take all of numbers within ...

[anony@mous-pc ~]$ cat some.txt
005
003
110
069
002
008
004
245
009
007
006

... and move desired numbers wanted moved (or any other strings) to top in exact order given in code executed, like so:

[anony@mous-pc ~]$ cat some.txt
002
004
006
008
005
003
110
069
245
009
007

How can this code be reversed to make these numbers order at the bottom of the .txt rather than at the top?

3

Change 0 in the ed script to $. The $ addresses the last line of the editing buffer.

$ { printf 'g?%s?m$\n' 008 006 004 002; echo 'wq'; } | ed -s file.txt
$ cat file.txt
005
003
110
069
245
009
007
008
006
004
002

Would you want them in reverse order (the order you had in the question), you would have to reverse the list of patterns.

$ { printf 'g?%s?m$\n' 002 004 006 008; echo 'wq'; } | ed -s file.txt
$ cat file.txt
005
003
110
069
245
009
007
002
004
006
008

Or, for that matter,

{ printf 'g?%s?m$\n' 008 006 004 002 | tac; echo 'wq'; } | ed -s file.txt

... if you have tac from GNU coreutils installed. On some systems (BSD) you may use tail -r in place of tac.

  • ... and you can use ( ) or { } ? – Anonymous May 20 at 22:07
  • @AnonymousUser ( ... ) executes a sub-shell. If I only want to group a set of commands for the purpose of redirecting their output to the same place, I tend to use { ...; }, which is faster. It doesn't really matter here. – Kusalananda May 20 at 22:12
  • So you mean you wouldn't have to cd to the directory in the script? It would just know where things are? – Anonymous May 21 at 1:57
  • You said 0 is the only thing that needs to be changed to a $ to make the code work in reverse, but I noticed you piped the original printf options (please correct me on the proper word here, if not options) to tac. And then echo wq rather than using printf again which is already in the code. But why? Wouldn't keeping printf going make things simpler in more ways than one? It's not even less characters. So why, exactly? – Anonymous May 21 at 2:10
  • @AnonymousUser Changing the 0 to $ is the only thing that is needed to move lines to the end rather than to the top. I use echo for outputting strings that are not variable, such as wq. You may still use printf to do this. I used tac to reverse the command outputted by printf as an alternative to specifying the numbers in the opposite order. It's not clear by what you mean by "reverse", and whether this included reversing the order of the lines. – Kusalananda May 21 at 5:29
0

Store lines in separate containers depending on whether they need to move south or remain in place. Then when all lines have been looked at this way, print them in the desired order.

$ perl -ne 'push @{/_00[2468]$/ ? \@A : \@B}, $_}{print @B, @A' input.txt

You can do this with posix sed also:

$ sed -ne '
    /_00[2468]$/s//&/w data2468
    //!p
    $r data2468
' input.txt

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.