sed: replacing entries in the /etc/fstab












4














I'm in the process of hardening some of our systems. As part of that hardening process, I need to update a few entries in the /etc/fstab to limit the capabilities of some of the various partitions.



With that said, I would like be able to use a sed in-line replace to update the rows. Below is a snippet from the current /etc/fstab:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0


After the sed command is run I would like the file to look like the following:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


Basically, I need to add "nodev" to all the rows that are ext[2-4], that aren't the root partition.



The sed command that I put together comes close to doing this, but for whatever reason, I can't get the regex to not match the "/" partition, so it always updates that row also.



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


I would like to key off of the "/" surrounded by spaces, not the vg1-lv_root. The following works, but I don't like the solution because it's clunky:



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab | sed '/^[^#].*root.*ext[2-4]/s/defaults,nodev/defaults/' > /etc/fstab









share|improve this question




















  • 3




    Is this on a Linux machine? Can we assume GNU tools?
    – terdon
    Nov 12 '18 at 13:58
















4














I'm in the process of hardening some of our systems. As part of that hardening process, I need to update a few entries in the /etc/fstab to limit the capabilities of some of the various partitions.



With that said, I would like be able to use a sed in-line replace to update the rows. Below is a snippet from the current /etc/fstab:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0


After the sed command is run I would like the file to look like the following:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


Basically, I need to add "nodev" to all the rows that are ext[2-4], that aren't the root partition.



The sed command that I put together comes close to doing this, but for whatever reason, I can't get the regex to not match the "/" partition, so it always updates that row also.



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


I would like to key off of the "/" surrounded by spaces, not the vg1-lv_root. The following works, but I don't like the solution because it's clunky:



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab | sed '/^[^#].*root.*ext[2-4]/s/defaults,nodev/defaults/' > /etc/fstab









share|improve this question




















  • 3




    Is this on a Linux machine? Can we assume GNU tools?
    – terdon
    Nov 12 '18 at 13:58














4












4








4







I'm in the process of hardening some of our systems. As part of that hardening process, I need to update a few entries in the /etc/fstab to limit the capabilities of some of the various partitions.



With that said, I would like be able to use a sed in-line replace to update the rows. Below is a snippet from the current /etc/fstab:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0


After the sed command is run I would like the file to look like the following:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


Basically, I need to add "nodev" to all the rows that are ext[2-4], that aren't the root partition.



The sed command that I put together comes close to doing this, but for whatever reason, I can't get the regex to not match the "/" partition, so it always updates that row also.



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


I would like to key off of the "/" surrounded by spaces, not the vg1-lv_root. The following works, but I don't like the solution because it's clunky:



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab | sed '/^[^#].*root.*ext[2-4]/s/defaults,nodev/defaults/' > /etc/fstab









share|improve this question















I'm in the process of hardening some of our systems. As part of that hardening process, I need to update a few entries in the /etc/fstab to limit the capabilities of some of the various partitions.



With that said, I would like be able to use a sed in-line replace to update the rows. Below is a snippet from the current /etc/fstab:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0


After the sed command is run I would like the file to look like the following:



# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


Basically, I need to add "nodev" to all the rows that are ext[2-4], that aren't the root partition.



The sed command that I put together comes close to doing this, but for whatever reason, I can't get the regex to not match the "/" partition, so it always updates that row also.



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


I would like to key off of the "/" surrounded by spaces, not the vg1-lv_root. The following works, but I don't like the solution because it's clunky:



sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab | sed '/^[^#].*root.*ext[2-4]/s/defaults,nodev/defaults/' > /etc/fstab






text-processing awk sed regular-expression fstab






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 16:45









Rui F Ribeiro

39.1k1479130




39.1k1479130










asked Nov 12 '18 at 12:50









Jason

513




513








  • 3




    Is this on a Linux machine? Can we assume GNU tools?
    – terdon
    Nov 12 '18 at 13:58














  • 3




    Is this on a Linux machine? Can we assume GNU tools?
    – terdon
    Nov 12 '18 at 13:58








3




3




Is this on a Linux machine? Can we assume GNU tools?
– terdon
Nov 12 '18 at 13:58




Is this on a Linux machine? Can we assume GNU tools?
– terdon
Nov 12 '18 at 13:58










4 Answers
4






active

oldest

votes


















5














You could use awk to add the logic to add the string and column to reformat the final output file. Assuming you have write permissions to the /etc/ and /tmp/ folders



tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)


This would create the temporary file in the /tmp/ path in which you can write the awk output to and re-direct that back to the original file



awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab


The column -t part is just redundant and needed to look the output file more readable, rather to make it disordered and clunky.






share|improve this answer



















  • 1




    Thank you for the response. That's a cool way of solving the problem.
    – Jason
    Nov 12 '18 at 13:09






  • 3




    I undeleted this since it is a good and helpful answer.
    – terdon
    Nov 12 '18 at 13:46










  • Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
    – Inian
    Nov 12 '18 at 13:48








  • 1




    Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
    – terdon
    Nov 12 '18 at 13:51










  • You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
    – JoL
    Nov 12 '18 at 18:54





















5














Here's a simpler sed approach:



$ sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


The trick is to look for whitespace followed by a / and one or more non-whitespace characters (s/S+), then ext[2-4] but only if preceded by whitespace (s+ext[2-4]), more whitespace and defaults. That should only match the cases you are interested in. So if it does match, replace the entire match with itself plus nodev: 1,nodev.



I am not sure how portable this is, however. The -E for extended regular expressions is supported by many sed implementations, but it isn't POSIX. For a more portable approach, you can try the same idea in Perl:



$ perl -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root / ext4 defaults 1 1
/dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
tmpfs /dev/shm tmpfs defaults 0 0


In both cases, to edit the file in place, use -i:



perl -i -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab


Or, for BSD or OSX sed:



sed -i '' -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 


Note that the above assume that the defaults option will either be the only one or, at least, the last one. They will fail if you have something like nodev,defaults for example.






share|improve this answer































    3














    Of course, ten minutes after posting the question, I was finally able to get it to do what I want with the following:



    sed -r '/^[^#].*[ t]+/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


    If someone has a cleaner or more foolproof answer, I'd love to hear it. Thanks!






    share|improve this answer























    • Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
      – Jason
      Nov 12 '18 at 13:26






    • 1




      Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
      – terdon
      Nov 12 '18 at 13:55



















    0














    Excluding matches are difficult to maintain. It's safer to only match the partition you want. And, for only matching one line, the trailing 'g' isn't necessary.



    sed -r 's#(/homes.*defaults)s#1,nodev #' /etc/fstab 





    share|improve this answer





















      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "106"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f481257%2fsed-replacing-entries-in-the-etc-fstab%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5














      You could use awk to add the logic to add the string and column to reformat the final output file. Assuming you have write permissions to the /etc/ and /tmp/ folders



      tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)


      This would create the temporary file in the /tmp/ path in which you can write the awk output to and re-direct that back to the original file



      awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab


      The column -t part is just redundant and needed to look the output file more readable, rather to make it disordered and clunky.






      share|improve this answer



















      • 1




        Thank you for the response. That's a cool way of solving the problem.
        – Jason
        Nov 12 '18 at 13:09






      • 3




        I undeleted this since it is a good and helpful answer.
        – terdon
        Nov 12 '18 at 13:46










      • Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
        – Inian
        Nov 12 '18 at 13:48








      • 1




        Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
        – terdon
        Nov 12 '18 at 13:51










      • You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
        – JoL
        Nov 12 '18 at 18:54


















      5














      You could use awk to add the logic to add the string and column to reformat the final output file. Assuming you have write permissions to the /etc/ and /tmp/ folders



      tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)


      This would create the temporary file in the /tmp/ path in which you can write the awk output to and re-direct that back to the original file



      awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab


      The column -t part is just redundant and needed to look the output file more readable, rather to make it disordered and clunky.






      share|improve this answer



















      • 1




        Thank you for the response. That's a cool way of solving the problem.
        – Jason
        Nov 12 '18 at 13:09






      • 3




        I undeleted this since it is a good and helpful answer.
        – terdon
        Nov 12 '18 at 13:46










      • Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
        – Inian
        Nov 12 '18 at 13:48








      • 1




        Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
        – terdon
        Nov 12 '18 at 13:51










      • You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
        – JoL
        Nov 12 '18 at 18:54
















      5












      5








      5






      You could use awk to add the logic to add the string and column to reformat the final output file. Assuming you have write permissions to the /etc/ and /tmp/ folders



      tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)


      This would create the temporary file in the /tmp/ path in which you can write the awk output to and re-direct that back to the original file



      awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab


      The column -t part is just redundant and needed to look the output file more readable, rather to make it disordered and clunky.






      share|improve this answer














      You could use awk to add the logic to add the string and column to reformat the final output file. Assuming you have write permissions to the /etc/ and /tmp/ folders



      tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)


      This would create the temporary file in the /tmp/ path in which you can write the awk output to and re-direct that back to the original file



      awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab


      The column -t part is just redundant and needed to look the output file more readable, rather to make it disordered and clunky.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 12 '18 at 13:10

























      answered Nov 12 '18 at 13:05









      Inian

      3,860824




      3,860824








      • 1




        Thank you for the response. That's a cool way of solving the problem.
        – Jason
        Nov 12 '18 at 13:09






      • 3




        I undeleted this since it is a good and helpful answer.
        – terdon
        Nov 12 '18 at 13:46










      • Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
        – Inian
        Nov 12 '18 at 13:48








      • 1




        Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
        – terdon
        Nov 12 '18 at 13:51










      • You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
        – JoL
        Nov 12 '18 at 18:54
















      • 1




        Thank you for the response. That's a cool way of solving the problem.
        – Jason
        Nov 12 '18 at 13:09






      • 3




        I undeleted this since it is a good and helpful answer.
        – terdon
        Nov 12 '18 at 13:46










      • Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
        – Inian
        Nov 12 '18 at 13:48








      • 1




        Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
        – terdon
        Nov 12 '18 at 13:51










      • You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
        – JoL
        Nov 12 '18 at 18:54










      1




      1




      Thank you for the response. That's a cool way of solving the problem.
      – Jason
      Nov 12 '18 at 13:09




      Thank you for the response. That's a cool way of solving the problem.
      – Jason
      Nov 12 '18 at 13:09




      3




      3




      I undeleted this since it is a good and helpful answer.
      – terdon
      Nov 12 '18 at 13:46




      I undeleted this since it is a good and helpful answer.
      – terdon
      Nov 12 '18 at 13:46












      Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
      – Inian
      Nov 12 '18 at 13:48






      Thanks @terdon, I saw OP's comment of having to use sed and without using temporary file
      – Inian
      Nov 12 '18 at 13:48






      1




      1




      Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
      – terdon
      Nov 12 '18 at 13:51




      Well, @Jason (and Inian) if you have access to a newish GNU awk (which you do if you're on Linux), you can do gawk -iinplace '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' OFS="t" /etc/fstab. Not as pretty as column, but it uses a tab for output which looks cleaner than a space and it will edit in place.
      – terdon
      Nov 12 '18 at 13:51












      You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
      – JoL
      Nov 12 '18 at 18:54






      You can avoid the tempfile by using sponge, i.e. awk ... | column ... | sponge /etc/fstab. Sponge will wait until it's read the entirety of stdin ("soaking it up") before writing to the file specified.
      – JoL
      Nov 12 '18 at 18:54















      5














      Here's a simpler sed approach:



      $ sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
      # /etc/fstab
      # Created by anaconda on Wed Feb 21 09:37:23 2018
      /dev/mapper/vg1-lv_root / ext4 defaults 1 1
      /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
      tmpfs /dev/shm tmpfs defaults 0 0


      The trick is to look for whitespace followed by a / and one or more non-whitespace characters (s/S+), then ext[2-4] but only if preceded by whitespace (s+ext[2-4]), more whitespace and defaults. That should only match the cases you are interested in. So if it does match, replace the entire match with itself plus nodev: 1,nodev.



      I am not sure how portable this is, however. The -E for extended regular expressions is supported by many sed implementations, but it isn't POSIX. For a more portable approach, you can try the same idea in Perl:



      $ perl -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
      # /etc/fstab
      # Created by anaconda on Wed Feb 21 09:37:23 2018
      /dev/mapper/vg1-lv_root / ext4 defaults 1 1
      /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
      tmpfs /dev/shm tmpfs defaults 0 0


      In both cases, to edit the file in place, use -i:



      perl -i -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
      sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab


      Or, for BSD or OSX sed:



      sed -i '' -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 


      Note that the above assume that the defaults option will either be the only one or, at least, the last one. They will fail if you have something like nodev,defaults for example.






      share|improve this answer




























        5














        Here's a simpler sed approach:



        $ sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
        # /etc/fstab
        # Created by anaconda on Wed Feb 21 09:37:23 2018
        /dev/mapper/vg1-lv_root / ext4 defaults 1 1
        /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
        tmpfs /dev/shm tmpfs defaults 0 0


        The trick is to look for whitespace followed by a / and one or more non-whitespace characters (s/S+), then ext[2-4] but only if preceded by whitespace (s+ext[2-4]), more whitespace and defaults. That should only match the cases you are interested in. So if it does match, replace the entire match with itself plus nodev: 1,nodev.



        I am not sure how portable this is, however. The -E for extended regular expressions is supported by many sed implementations, but it isn't POSIX. For a more portable approach, you can try the same idea in Perl:



        $ perl -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
        # /etc/fstab
        # Created by anaconda on Wed Feb 21 09:37:23 2018
        /dev/mapper/vg1-lv_root / ext4 defaults 1 1
        /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
        tmpfs /dev/shm tmpfs defaults 0 0


        In both cases, to edit the file in place, use -i:



        perl -i -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
        sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab


        Or, for BSD or OSX sed:



        sed -i '' -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 


        Note that the above assume that the defaults option will either be the only one or, at least, the last one. They will fail if you have something like nodev,defaults for example.






        share|improve this answer


























          5












          5








          5






          Here's a simpler sed approach:



          $ sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          # /etc/fstab
          # Created by anaconda on Wed Feb 21 09:37:23 2018
          /dev/mapper/vg1-lv_root / ext4 defaults 1 1
          /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
          tmpfs /dev/shm tmpfs defaults 0 0


          The trick is to look for whitespace followed by a / and one or more non-whitespace characters (s/S+), then ext[2-4] but only if preceded by whitespace (s+ext[2-4]), more whitespace and defaults. That should only match the cases you are interested in. So if it does match, replace the entire match with itself plus nodev: 1,nodev.



          I am not sure how portable this is, however. The -E for extended regular expressions is supported by many sed implementations, but it isn't POSIX. For a more portable approach, you can try the same idea in Perl:



          $ perl -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          # /etc/fstab
          # Created by anaconda on Wed Feb 21 09:37:23 2018
          /dev/mapper/vg1-lv_root / ext4 defaults 1 1
          /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
          tmpfs /dev/shm tmpfs defaults 0 0


          In both cases, to edit the file in place, use -i:



          perl -i -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab


          Or, for BSD or OSX sed:



          sed -i '' -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 


          Note that the above assume that the defaults option will either be the only one or, at least, the last one. They will fail if you have something like nodev,defaults for example.






          share|improve this answer














          Here's a simpler sed approach:



          $ sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          # /etc/fstab
          # Created by anaconda on Wed Feb 21 09:37:23 2018
          /dev/mapper/vg1-lv_root / ext4 defaults 1 1
          /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
          tmpfs /dev/shm tmpfs defaults 0 0


          The trick is to look for whitespace followed by a / and one or more non-whitespace characters (s/S+), then ext[2-4] but only if preceded by whitespace (s+ext[2-4]), more whitespace and defaults. That should only match the cases you are interested in. So if it does match, replace the entire match with itself plus nodev: 1,nodev.



          I am not sure how portable this is, however. The -E for extended regular expressions is supported by many sed implementations, but it isn't POSIX. For a more portable approach, you can try the same idea in Perl:



          $ perl -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          # /etc/fstab
          # Created by anaconda on Wed Feb 21 09:37:23 2018
          /dev/mapper/vg1-lv_root / ext4 defaults 1 1
          /dev/mapper/vg1-lv_home /home ext4 defaults,nodev 1 2
          tmpfs /dev/shm tmpfs defaults 0 0


          In both cases, to edit the file in place, use -i:



          perl -i -pe 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 
          sed -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab


          Or, for BSD or OSX sed:



          sed -i '' -E 's|(s/S+s+ext[2-4]s+defaults)|1,nodev|' fstab 


          Note that the above assume that the defaults option will either be the only one or, at least, the last one. They will fail if you have something like nodev,defaults for example.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 12 '18 at 14:12

























          answered Nov 12 '18 at 13:54









          terdon

          128k31249423




          128k31249423























              3














              Of course, ten minutes after posting the question, I was finally able to get it to do what I want with the following:



              sed -r '/^[^#].*[ t]+/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


              If someone has a cleaner or more foolproof answer, I'd love to hear it. Thanks!






              share|improve this answer























              • Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
                – Jason
                Nov 12 '18 at 13:26






              • 1




                Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
                – terdon
                Nov 12 '18 at 13:55
















              3














              Of course, ten minutes after posting the question, I was finally able to get it to do what I want with the following:



              sed -r '/^[^#].*[ t]+/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


              If someone has a cleaner or more foolproof answer, I'd love to hear it. Thanks!






              share|improve this answer























              • Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
                – Jason
                Nov 12 '18 at 13:26






              • 1




                Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
                – terdon
                Nov 12 '18 at 13:55














              3












              3








              3






              Of course, ten minutes after posting the question, I was finally able to get it to do what I want with the following:



              sed -r '/^[^#].*[ t]+/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


              If someone has a cleaner or more foolproof answer, I'd love to hear it. Thanks!






              share|improve this answer














              Of course, ten minutes after posting the question, I was finally able to get it to do what I want with the following:



              sed -r '/^[^#].*[ t]+/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab


              If someone has a cleaner or more foolproof answer, I'd love to hear it. Thanks!







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 12 '18 at 13:45









              terdon

              128k31249423




              128k31249423










              answered Nov 12 '18 at 13:11









              Jason

              513




              513












              • Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
                – Jason
                Nov 12 '18 at 13:26






              • 1




                Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
                – terdon
                Nov 12 '18 at 13:55


















              • Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
                – Jason
                Nov 12 '18 at 13:26






              • 1




                Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
                – terdon
                Nov 12 '18 at 13:55
















              Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
              – Jason
              Nov 12 '18 at 13:26




              Yeah, the main question was, "what am I doing wrong with my regular expression?". Sorry, I probably should have been more clear in my original post. I would prefer to not create temporary files if I can solve the problem with a sed one-liner.
              – Jason
              Nov 12 '18 at 13:26




              1




              1




              Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
              – terdon
              Nov 12 '18 at 13:55




              Why are you assuming t? As far as I know, all fstab needs is whitespace so there's no reason you will always have a tab there.
              – terdon
              Nov 12 '18 at 13:55











              0














              Excluding matches are difficult to maintain. It's safer to only match the partition you want. And, for only matching one line, the trailing 'g' isn't necessary.



              sed -r 's#(/homes.*defaults)s#1,nodev #' /etc/fstab 





              share|improve this answer


























                0














                Excluding matches are difficult to maintain. It's safer to only match the partition you want. And, for only matching one line, the trailing 'g' isn't necessary.



                sed -r 's#(/homes.*defaults)s#1,nodev #' /etc/fstab 





                share|improve this answer
























                  0












                  0








                  0






                  Excluding matches are difficult to maintain. It's safer to only match the partition you want. And, for only matching one line, the trailing 'g' isn't necessary.



                  sed -r 's#(/homes.*defaults)s#1,nodev #' /etc/fstab 





                  share|improve this answer












                  Excluding matches are difficult to maintain. It's safer to only match the partition you want. And, for only matching one line, the trailing 'g' isn't necessary.



                  sed -r 's#(/homes.*defaults)s#1,nodev #' /etc/fstab 






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 4:28









                  hellork

                  665




                  665






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f481257%2fsed-replacing-entries-in-the-etc-fstab%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values