0

I've got a head command to get the first line of a file and a sed command to insert before the first line of a file. How do I combine these so I can insert the extracted first line of one file before the first line of another file.

Get first line of a file

head -n 1 file_to_get_first_line_from

Insert before first line

sed -i '1 i\insert_this_in_the_first_line' file_to_intert_into
2

If your file_to_insert_into does not end with trailing newline:

$ cat <<IN > file_to_insert_into
$(head -n1 file_to_get_first_line_from; cat file_to_insert_into)
IN
  • Prolly the best/fastest in this particular case so +. Can't be reused though if requirements change (e.g. insert before 21st line). – don_crissti Apr 5 '16 at 19:15
1

The most portable way to do this is by using POSIX specified features of ex.

$ cat file1
Jack and Jill
Went up the hill
To fetch a pail of water.

$ cat file2
Nursery Rhymes:
Epic Poems:
Classic Literature:

$ printf '%s\n' '0r !head -n 1 file2' x | ex file1

$ cat file1
Nursery Rhymes:
Jack and Jill
Went up the hill
To fetch a pail of water.
  • printf is used to send commands to ex.
  • 0 is the address given to the read command; it tells ex to read in the specified text "after line 0" (i.e. before line 1).

  • !head -n 1 file2 means that instead of reading text directly from a file (a whole file), the head command is executed first and its output is read in (at the specified position, line 0).

  • x means save and exit.

This is fully POSIX compliant and portable.


If you were scripting this it would be good practice to check your assumptions: That file2 exists and is readable, and that file1 is readable and writable if it exists.

if [ -r file2 ] && [ -f file2 ] && { ! [ -e file1 ] || { [ -r file1 ] && [ -w file1 ];};}; then
  printf '%s\n' '0r !head -n 1 file2' x | ex file1
fi
0

With Vim and head:

vim -Nesc '0r !head -n1 file_to_get_first_line_from' +wq file_to_insert_into
  • -Nes starts no-compatible, silent, ex-mode, which is useful when you want to script tasks with Vim.
  • -c '0r !<cmd>' inserts the output of the command <cmd> before the first line. The command here is, of course, the head command.
  • +wq saves and closes the file.
0

Updated: Thanks to @Wildcard for pointing out GNU Sed difference

BSD sed

Try on your terminal:

sed -i '' "1i\
$(head -n 1 file_to_get_first_line_from)" file_to_insert_into
  • This means start typing sed -i '' "1i\, then hit enter to continue the rest of the command

Explanation

  • Helps combine your two original commands via Bash command substitution $( ). Replaces whatever bash commands are inside $( ), with its output
  • We change ' literal quotes to " quotes in order to allow Bash to act while still using quotes for sed to properly see one sed command

GNU sed

Or if you have GNU sed:

sed -i "1i $(head -n 1 file_to_get_first_line_from)" file_to_insert_into
  • Tested with sed (GNU sed) 4.2.2. To see your sed version: sed --version
  • GNU sed can omit the \ and newline. info sed, under sed Programs, Common Commands:

As a GNU extension, if between the 'a' and the newline there is other than a whitespace-'\' sequence, then the text of this line, starting at the first non-whitespace character after the 'a', is taken as the first line of the TEXT block. (This enables a simplification in scripting a one-line add.) This extension also works with the 'i' and 'c' commands.

Additional info

  • Optionally, there is a shorter version of the head command: head -1. However info head claims this is a obsolete option syntax -[NUM]... that head supports, and recommends for "standard hosts" to use the -n NUM syntax instead, so we can just continue to use your original head -n 1 syntax here
  • This depends on GNU sed; POSIX compatibility requires a backslash and newline after i to delimit the text to be inserted. – Wildcard Apr 5 '16 at 17:57
  • Thanks for pointing that out @Wildcard. Answer updated about this difference. – clarity123 Apr 5 '16 at 18:29

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.