3 I don't think that command would have worked; must have missed it in my original typing. It's fixed now.
source | link

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

A more complicated, but convergent, bit of code that will check whether the beginning of services EXACTLY matches the entirety of header, byte for byte, and IF NOT will then prepend the entire contents of header to services and save the changes, follows.

This is fully POSIX compliant.

dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

A much simpler version, using GNU cmp's "-n" option:

cmp -sn "$(wc -c <header)" header services ||
  printf '%s\n' '0r header' x | ex services

Of course, neither of these is smart enough to check for PARTIAL matches, but that's getting far beyond the ability of a simple one liner, since guesswork would be intrinsically involved.

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

A more complicated, but convergent, bit of code that will check whether the beginning of services EXACTLY matches the entirety of header, byte for byte, and IF NOT will then prepend the entire contents of header to services and save the changes, follows.

This is fully POSIX compliant.

dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

A much simpler version, using GNU cmp's "-n" option:

cmp -sn "$(wc -c <header)" ||
  printf '%s\n' '0r header' x | ex services

Of course, neither of these is smart enough to check for PARTIAL matches, but that's getting far beyond the ability of a simple one liner, since guesswork would be intrinsically involved.

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

A more complicated, but convergent, bit of code that will check whether the beginning of services EXACTLY matches the entirety of header, byte for byte, and IF NOT will then prepend the entire contents of header to services and save the changes, follows.

This is fully POSIX compliant.

dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

A much simpler version, using GNU cmp's "-n" option:

cmp -sn "$(wc -c <header)" header services ||
  printf '%s\n' '0r header' x | ex services

Of course, neither of these is smart enough to check for PARTIAL matches, but that's getting far beyond the ability of a simple one liner, since guesswork would be intrinsically involved.

2 added 803 characters in body
source | link

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

A more complicated, but convergent, bit of code that will check whether the beginning of services EXACTLY matches the entirety of header, byte for byte, and IF NOT will then prepend the entire contents of header to services and save the changes, follows.

This is fully POSIX compliant.

dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

A much simpler version, using GNU cmp's "-n" option:

cmp -sn "$(wc -c <header)" ||
  printf '%s\n' '0r header' x | ex services

Of course, neither of these is smart enough to check for PARTIAL matches, but that's getting far beyond the ability of a simple one liner, since guesswork would be intrinsically involved.

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents

A more complicated, but convergent, bit of code that will check whether the beginning of services EXACTLY matches the entirety of header, byte for byte, and IF NOT will then prepend the entire contents of header to services and save the changes, follows.

This is fully POSIX compliant.

dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

A much simpler version, using GNU cmp's "-n" option:

cmp -sn "$(wc -c <header)" ||
  printf '%s\n' '0r header' x | ex services

Of course, neither of these is smart enough to check for PARTIAL matches, but that's getting far beyond the ability of a simple one liner, since guesswork would be intrinsically involved.

1
source | link

Relatively elegant solution using POSIX specified file editor ex—at least elegant in the sense that this will handle any arbitrary contents rather than depending on a specific format (trailing backslashes) or a specific absence of format.

printf '0r headerfile\nx\n' | ex file-with-contents

This will open file-with-contents in ex, read in the full contents of the headerfile at the very top, and then save the modified buffer back to file-with-contents.

If performance is a SEVERE concern and the files are huge this may not be the right way for you, but (a) there is no performant general way to prepend data to a file and (b) I don't expect you will be editing your /etc/services file that often.


A slightly cleaner syntax (the way I would actually code this):

printf '%s\n' '0r headerfile' x | ex file-with-contents