What's the easiest way for me to script moving the last line of a text file to the Nth line? I have a whole directory full of files that need the exact same treatment.

Update: My solution in replies!

#AskFedi #AskFediverse #LazyWeb

Turns out vim can do this directly in terminal:

vim +'$-0,$m0’ +'wq' FILE

Will move the last line ($-0) to the first line ($m0) and write the result (+wq).

Throw this in a loop and it did exactly what I needed:

for FILE in *.html; do vim +'$-0,$m7' +'wq' $FILE; done

^ loops through all html files in current directory, moves the last line to the 7th line.

Did I just move an HTML image to front matter on 120 blog posts at once?

Yes. Yes I did.

@josh Assuming N is the same for all files, maybe a two-step combo of sed and tail? Eg for N=6

sed -i "6i $(tail -n 1 $file)" && sed -i '$d' $file

Untested, probably totally wrong if you are on a Mac, will most certainly fail if the last line contains a $ etc

I'm also sure some professional sysadmin will cry over this "obviously bad idea"

@josh Based on the timestamps on your own response, it took me at least 6 minutes to type that in on my phone. On-screen keyboard suck for code!

@tkissing My solution was very similar, but using vim!

I knew enough about the content (already mostly normalized via many regex and various find/replace steps) that I knew for sure every file was the same.

Worked really well for what I needed, and a super useful thing to know how to do!

@josh

Not that it adds much to your solution, but just out of interest I tried using 'ed'. I learnt the rudiments of this editor when setting up several DECstations using Ultrix in the 1990s which didn't have vim installed at that time:

$ for i in {01..10}; do echo "Line $i"; done > edit_test.dat

$ line=3; echo -e "m${line}\n,w" | ed -s edit_test.dat

This moves line 10 in the file after line 3.

Of course vim uses ed commands in command mode, so this is not all that exciting!