6

I have this file:

a
b
c
d
e
f

I want the last line to be copied to before the first line, so I'll get the following result:

f
a
b
c
d
e
f

How can I do it in sed or awk?

9

Pure sed:

sed 'H;1h;$!d;G' file.txt

All lines are collected in the hold space, then appended to the last line:

  • H appends the current line to the hold space. Unfortunally this will start the hold space with a newline, so 1h for the first line, the hold space gets overwritte with that line without preceeding newline
  • $!d means if this is not (!) the last line ($), delete the line, because we don't want to print it yet
  • G is only executed for the last line, because for other lines the d stopped processing. Now all lines (first to last) we collected in the hold space get appended to the current (last) line with the G command and everything gets printed at the end of the script.
10

With ed:

$ printf '$t0\n,p\n' | ed -s file
f
a
b
c
d
e
f

The t command in ed transfers/copies a line from the addressed line (here $ for the last line) to after the line addressed by its argument (here 0, i.e. insert before the first line). The ,p command prints the contents of the editing buffer (change this to w to write the result back into the file).

9

or simply like this, without sed or other

tail -1 list && cat list
6

Another sed alternative would be:

sed '$!d; r infile' infile

delete all lines except last, next read and output whole file.

  • This is the best solution, very neat and inventive. – Rakesh Sharma Apr 30 at 3:37
  • But there is a problem: I get the text from stdin via pipe. There is no way I can use that r infile command. – Seninha May 1 at 22:38
3

GNU awk:

awk 'ENDFILE { if(NR==FNR) print } NR!=FNR' infile{,}

Portable awk:

awk 'NR!=FNR && !f { f=1; print p } NR!=FNR; { p=$0 }' infile{,}
2

Reverse the file, remember the first line and print it after the last line, then re-reverse the file:

tac file | awk 'FNR == 1 {last=$0} {print} END {print last}' | tac
# or
tac file | sed -n '1h; p; ${x;p}' | tac
  • 1
    tac file | sed '1h;$G' | tac – Rakesh Sharma Apr 29 at 17:16
1

Try this,

 tail -n1 file | xargs -I '{}' sed '1i{}' file
  • tail -n1 will print the last line of the file
  • xargs -I will pass the tail output to sed
  • sed '1i will insert the context in first line

if the output looks file, add -i option to sed to do inline edit

  • That assumes GNU sed and that the first line doesn't contain quotes nor backslashes and doesn't start nor end with blanks. – Stéphane Chazelas Apr 29 at 10:04
1

Tried with below sed command and it worked fine too

command

k=`sed -n '$p' filename `
sed '1i '$k'' filename

output

f
a
b
c
d
e
f

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.