Skip to main content

How to modify this `printf` code to accept input in first to last order, or flip output? [Resolved]

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 file.txt
005
003
110
069
002
008
004
245
009
007
006

... and move desired numbers (or other strings) to top, BUT in reverse order of executed code ...

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

... just so long as you give the order in reverse, the order will be first to last (opposite order), or ... others may call it top to bottom formatting ... so one more time, to achieve first to last order I had to execute this way ...

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

BUT, how can one input their numbers (or strings) in the order they intended for being first to last and still achieve first to last order?

If not possible to change inputted results, would sed be able to change output results and flip or reverse them before saving file.txt?


Question Credit: Anonymous
Question Reference
Asked May 24, 2019
Posted Under: Unix Linux
7 views
1 Answers

$ perl -lne '
   /00[2468]$/ ? $h{$_} : $A[@A] = $_; }{
   print for @h{qw/008 006 004 002/}, @A;
' file.txt

Store in separate containers matching and nonmatching lines. When time comes to print them, pull out the order from the anonymous array keying into the hash %h.

Explanation:

  • As we read in each line, look to see it contains the matching line, those that end in 2,4,6, or 8. Store them in the hash %h with the key being the whole matching line $h{$_}.
  • OTW, for a no match, push the nonmatching line to the back of the array @A.
  • After we've seen the end of file, we print the hash %h first. As you would be aware that access of hashes is inherently random. But we must impose an order since that was one of your requirements. So we prescribe the order by listing the keys in the order you want them to appear: qw/008 006 004 002/ This is an anonymous array. This is gonna print $h{008} followed by $h{006} and so on.
  • After that the array @A is printed which had the non matched lines. Q.E.D.
  • Now, if you were to interchange the order of printing the array @A and the hash slice @h{...} you should see the matching elements move south instead of north.
  • The code just prints to the stdout, which you would have to move back into the original: perl '...' file.txt > /tmp/file.txt; mv /tmp/file.txt file.txt

credit: Rakesh Sharma
Answered May 24, 2019
Your Answer
D:\Adnan\Candoerz\CandoProject\vQA