Remove absolute path from file with bash

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I have file "list.txt" containing absolute paths to other files



/home/lin/bash/aaa
/home/lin/bash/song.mp3
/home/lin/bash/doc.html
/home/lin/bash/directory


I want to assign path to variable



path="/home/lin/bash/song.mp3"


and then remove whole line with that path. I've tried



sed -i '$path' list.txt


and many other command with grep, echo but nothing works.







share|improve this question
























    up vote
    0
    down vote

    favorite












    I have file "list.txt" containing absolute paths to other files



    /home/lin/bash/aaa
    /home/lin/bash/song.mp3
    /home/lin/bash/doc.html
    /home/lin/bash/directory


    I want to assign path to variable



    path="/home/lin/bash/song.mp3"


    and then remove whole line with that path. I've tried



    sed -i '$path' list.txt


    and many other command with grep, echo but nothing works.







    share|improve this question






















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have file "list.txt" containing absolute paths to other files



      /home/lin/bash/aaa
      /home/lin/bash/song.mp3
      /home/lin/bash/doc.html
      /home/lin/bash/directory


      I want to assign path to variable



      path="/home/lin/bash/song.mp3"


      and then remove whole line with that path. I've tried



      sed -i '$path' list.txt


      and many other command with grep, echo but nothing works.







      share|improve this question












      I have file "list.txt" containing absolute paths to other files



      /home/lin/bash/aaa
      /home/lin/bash/song.mp3
      /home/lin/bash/doc.html
      /home/lin/bash/directory


      I want to assign path to variable



      path="/home/lin/bash/song.mp3"


      and then remove whole line with that path. I've tried



      sed -i '$path' list.txt


      and many other command with grep, echo but nothing works.









      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 22 at 15:04









      Mike Naplet

      62




      62




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          There are two problems with your solution. First since you're using single quotes for '$path' this expression is treated literally, and not like the variable $path. In order to solve this use double quotes "$path". But then you will face the second problem: you want to use slash / as a special sed-symbol and at the same time this symbol is present in paths, which will confuse sed. Therefore you have to use some other symbol instead of slash, for example, use comma



          $ sed -i "s,$path,," list.txt
          $ cat list.txt
          /home/lin/bash/aaa

          /home/lin/bash/doc.html
          /home/lin/bash/directory


          There is another beautiful approach, suggested by Tim Kennedy (see explanation of how it works in the discussion below), which does not leave the blank line



          $ sed -i ",$path,d" list.txt
          $ cat list.txt
          /home/lin/bash/aaa
          /home/lin/bash/doc.html
          /home/lin/bash/directory





          share|improve this answer


















          • 1




            sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
            – Tim Kennedy
            Jan 22 at 15:49










          • @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
            – John Smith
            Jan 22 at 16:08






          • 2




            Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
            – Tim Kennedy
            Jan 22 at 21:34











          • Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
            – Mike Naplet
            Jan 23 at 17:36










          • @MikeNaplet good reason to upvote his comments)
            – John Smith
            Jan 23 at 20:22

















          up vote
          2
          down vote













          Try grep approach once again - it'll work:



          grep -xv "$path" list.txt > tmp_$$ && mv tmp_$$ list.txt


          The final list.txt contents:



          /home/lin/bash/aaa
          /home/lin/bash/doc.html
          /home/lin/bash/directory





          share|improve this answer



























            up vote
            0
            down vote













            You could do this with GNU sed and double qoutes to expand the variable.



            sed -i.bak ":^$path$:d" list.txt


            • Here we used -i to have in-place replace/deletion of matched patters as in $path, the .bak is taking a backup of original list.txt file with to list.txt.bak

            • We used different separator to prevent failing sed with slashes / in $path will contain.

            • We used start of line ^ and end of line $ anchors to match the path in whole line not partially if matched.


            • We escaped opening first delimiter as it's mandatory when delimiter is other than slash /. in man sed documented.



              cregexpc
              Match lines matching the regular expression regexp.
              The c may be any character.


              actually this is telling sed that next character is our delimiter.







            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',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              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%2f418882%2fremove-absolute-path-from-file-with-bash%23new-answer', 'question_page');

              );

              Post as a guest






























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              0
              down vote



              accepted










              There are two problems with your solution. First since you're using single quotes for '$path' this expression is treated literally, and not like the variable $path. In order to solve this use double quotes "$path". But then you will face the second problem: you want to use slash / as a special sed-symbol and at the same time this symbol is present in paths, which will confuse sed. Therefore you have to use some other symbol instead of slash, for example, use comma



              $ sed -i "s,$path,," list.txt
              $ cat list.txt
              /home/lin/bash/aaa

              /home/lin/bash/doc.html
              /home/lin/bash/directory


              There is another beautiful approach, suggested by Tim Kennedy (see explanation of how it works in the discussion below), which does not leave the blank line



              $ sed -i ",$path,d" list.txt
              $ cat list.txt
              /home/lin/bash/aaa
              /home/lin/bash/doc.html
              /home/lin/bash/directory





              share|improve this answer


















              • 1




                sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
                – Tim Kennedy
                Jan 22 at 15:49










              • @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
                – John Smith
                Jan 22 at 16:08






              • 2




                Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
                – Tim Kennedy
                Jan 22 at 21:34











              • Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
                – Mike Naplet
                Jan 23 at 17:36










              • @MikeNaplet good reason to upvote his comments)
                – John Smith
                Jan 23 at 20:22














              up vote
              0
              down vote



              accepted










              There are two problems with your solution. First since you're using single quotes for '$path' this expression is treated literally, and not like the variable $path. In order to solve this use double quotes "$path". But then you will face the second problem: you want to use slash / as a special sed-symbol and at the same time this symbol is present in paths, which will confuse sed. Therefore you have to use some other symbol instead of slash, for example, use comma



              $ sed -i "s,$path,," list.txt
              $ cat list.txt
              /home/lin/bash/aaa

              /home/lin/bash/doc.html
              /home/lin/bash/directory


              There is another beautiful approach, suggested by Tim Kennedy (see explanation of how it works in the discussion below), which does not leave the blank line



              $ sed -i ",$path,d" list.txt
              $ cat list.txt
              /home/lin/bash/aaa
              /home/lin/bash/doc.html
              /home/lin/bash/directory





              share|improve this answer


















              • 1




                sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
                – Tim Kennedy
                Jan 22 at 15:49










              • @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
                – John Smith
                Jan 22 at 16:08






              • 2




                Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
                – Tim Kennedy
                Jan 22 at 21:34











              • Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
                – Mike Naplet
                Jan 23 at 17:36










              • @MikeNaplet good reason to upvote his comments)
                – John Smith
                Jan 23 at 20:22












              up vote
              0
              down vote



              accepted







              up vote
              0
              down vote



              accepted






              There are two problems with your solution. First since you're using single quotes for '$path' this expression is treated literally, and not like the variable $path. In order to solve this use double quotes "$path". But then you will face the second problem: you want to use slash / as a special sed-symbol and at the same time this symbol is present in paths, which will confuse sed. Therefore you have to use some other symbol instead of slash, for example, use comma



              $ sed -i "s,$path,," list.txt
              $ cat list.txt
              /home/lin/bash/aaa

              /home/lin/bash/doc.html
              /home/lin/bash/directory


              There is another beautiful approach, suggested by Tim Kennedy (see explanation of how it works in the discussion below), which does not leave the blank line



              $ sed -i ",$path,d" list.txt
              $ cat list.txt
              /home/lin/bash/aaa
              /home/lin/bash/doc.html
              /home/lin/bash/directory





              share|improve this answer














              There are two problems with your solution. First since you're using single quotes for '$path' this expression is treated literally, and not like the variable $path. In order to solve this use double quotes "$path". But then you will face the second problem: you want to use slash / as a special sed-symbol and at the same time this symbol is present in paths, which will confuse sed. Therefore you have to use some other symbol instead of slash, for example, use comma



              $ sed -i "s,$path,," list.txt
              $ cat list.txt
              /home/lin/bash/aaa

              /home/lin/bash/doc.html
              /home/lin/bash/directory


              There is another beautiful approach, suggested by Tim Kennedy (see explanation of how it works in the discussion below), which does not leave the blank line



              $ sed -i ",$path,d" list.txt
              $ cat list.txt
              /home/lin/bash/aaa
              /home/lin/bash/doc.html
              /home/lin/bash/directory






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 23 at 7:44

























              answered Jan 22 at 15:23









              John Smith

              95857




              95857







              • 1




                sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
                – Tim Kennedy
                Jan 22 at 15:49










              • @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
                – John Smith
                Jan 22 at 16:08






              • 2




                Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
                – Tim Kennedy
                Jan 22 at 21:34











              • Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
                – Mike Naplet
                Jan 23 at 17:36










              • @MikeNaplet good reason to upvote his comments)
                – John Smith
                Jan 23 at 20:22












              • 1




                sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
                – Tim Kennedy
                Jan 22 at 15:49










              • @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
                – John Smith
                Jan 22 at 16:08






              • 2




                Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
                – Tim Kennedy
                Jan 22 at 21:34











              • Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
                – Mike Naplet
                Jan 23 at 17:36










              • @MikeNaplet good reason to upvote his comments)
                – John Smith
                Jan 23 at 20:22







              1




              1




              sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
              – Tim Kennedy
              Jan 22 at 15:49




              sed -i "#$tmppath#d" list.txt will do the same without leaving behind that empty line.
              – Tim Kennedy
              Jan 22 at 15:49












              @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
              – John Smith
              Jan 22 at 16:08




              @Tim, beautiful solution, but I do not understand how it works)) p.s. if you do not mind, I will cite you in my answer.
              – John Smith
              Jan 22 at 16:08




              2




              2




              Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
              – Tim Kennedy
              Jan 22 at 21:34





              Your solution, "s,$tmppath,," is a sed substitution command. Using a pattern like /pattern/d tells sed to delete the line the pattern is in. Except, in this case, as you rightly pointed out, the delimiter needs to change because the pattern is full of / characters. I should have used commas in my example to make it more similar to yours, so it would be: ",$tmppath,d". In a nut shell, the delimiters identify the pattern to find, and the d is the delete command. And the leading backslash tells sed to ignore the , as a comma and use it as a delimiter.
              – Tim Kennedy
              Jan 22 at 21:34













              Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
              – Mike Naplet
              Jan 23 at 17:36




              Thank you all for answers. Solution suggested by Tim Kennedy looks the easiest for me.
              – Mike Naplet
              Jan 23 at 17:36












              @MikeNaplet good reason to upvote his comments)
              – John Smith
              Jan 23 at 20:22




              @MikeNaplet good reason to upvote his comments)
              – John Smith
              Jan 23 at 20:22












              up vote
              2
              down vote













              Try grep approach once again - it'll work:



              grep -xv "$path" list.txt > tmp_$$ && mv tmp_$$ list.txt


              The final list.txt contents:



              /home/lin/bash/aaa
              /home/lin/bash/doc.html
              /home/lin/bash/directory





              share|improve this answer
























                up vote
                2
                down vote













                Try grep approach once again - it'll work:



                grep -xv "$path" list.txt > tmp_$$ && mv tmp_$$ list.txt


                The final list.txt contents:



                /home/lin/bash/aaa
                /home/lin/bash/doc.html
                /home/lin/bash/directory





                share|improve this answer






















                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  Try grep approach once again - it'll work:



                  grep -xv "$path" list.txt > tmp_$$ && mv tmp_$$ list.txt


                  The final list.txt contents:



                  /home/lin/bash/aaa
                  /home/lin/bash/doc.html
                  /home/lin/bash/directory





                  share|improve this answer












                  Try grep approach once again - it'll work:



                  grep -xv "$path" list.txt > tmp_$$ && mv tmp_$$ list.txt


                  The final list.txt contents:



                  /home/lin/bash/aaa
                  /home/lin/bash/doc.html
                  /home/lin/bash/directory






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 22 at 15:13









                  RomanPerekhrest

                  22.4k12144




                  22.4k12144




















                      up vote
                      0
                      down vote













                      You could do this with GNU sed and double qoutes to expand the variable.



                      sed -i.bak ":^$path$:d" list.txt


                      • Here we used -i to have in-place replace/deletion of matched patters as in $path, the .bak is taking a backup of original list.txt file with to list.txt.bak

                      • We used different separator to prevent failing sed with slashes / in $path will contain.

                      • We used start of line ^ and end of line $ anchors to match the path in whole line not partially if matched.


                      • We escaped opening first delimiter as it's mandatory when delimiter is other than slash /. in man sed documented.



                        cregexpc
                        Match lines matching the regular expression regexp.
                        The c may be any character.


                        actually this is telling sed that next character is our delimiter.







                      share|improve this answer


























                        up vote
                        0
                        down vote













                        You could do this with GNU sed and double qoutes to expand the variable.



                        sed -i.bak ":^$path$:d" list.txt


                        • Here we used -i to have in-place replace/deletion of matched patters as in $path, the .bak is taking a backup of original list.txt file with to list.txt.bak

                        • We used different separator to prevent failing sed with slashes / in $path will contain.

                        • We used start of line ^ and end of line $ anchors to match the path in whole line not partially if matched.


                        • We escaped opening first delimiter as it's mandatory when delimiter is other than slash /. in man sed documented.



                          cregexpc
                          Match lines matching the regular expression regexp.
                          The c may be any character.


                          actually this is telling sed that next character is our delimiter.







                        share|improve this answer
























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          You could do this with GNU sed and double qoutes to expand the variable.



                          sed -i.bak ":^$path$:d" list.txt


                          • Here we used -i to have in-place replace/deletion of matched patters as in $path, the .bak is taking a backup of original list.txt file with to list.txt.bak

                          • We used different separator to prevent failing sed with slashes / in $path will contain.

                          • We used start of line ^ and end of line $ anchors to match the path in whole line not partially if matched.


                          • We escaped opening first delimiter as it's mandatory when delimiter is other than slash /. in man sed documented.



                            cregexpc
                            Match lines matching the regular expression regexp.
                            The c may be any character.


                            actually this is telling sed that next character is our delimiter.







                          share|improve this answer














                          You could do this with GNU sed and double qoutes to expand the variable.



                          sed -i.bak ":^$path$:d" list.txt


                          • Here we used -i to have in-place replace/deletion of matched patters as in $path, the .bak is taking a backup of original list.txt file with to list.txt.bak

                          • We used different separator to prevent failing sed with slashes / in $path will contain.

                          • We used start of line ^ and end of line $ anchors to match the path in whole line not partially if matched.


                          • We escaped opening first delimiter as it's mandatory when delimiter is other than slash /. in man sed documented.



                            cregexpc
                            Match lines matching the regular expression regexp.
                            The c may be any character.


                            actually this is telling sed that next character is our delimiter.








                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jan 22 at 16:21

























                          answered Jan 22 at 15:16









                          αғsнιη

                          15.2k92462




                          15.2k92462






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f418882%2fremove-absolute-path-from-file-with-bash%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Bahrain

                              Postfix configuration issue with fips on centos 7; mailgun relay