unix - Is it possible to sed -i from a text file to another text file?

06
2014-04
  • gtbono

    I'm coding a shell script on my Debian box and there's a line on the script that needs to delete some emails from a textfile that is full of emails, like this:

    sed -i '/[email protected]\|[email protected]\|[email protected]/d' /myfolder/my_email_list.txt
    

    This command works but as this list is getting kinda big, I was thinking if there is a way for me to store all the emails that I want sed to delete on a list (text file), because when I need a new email to be added, I would just edit the list instead of editing the script and including it in the expression.

    Is something like this able to be done?

  • Answers
  • terdon

    There may well be a way of doing this natively in sed but here are some other options:

    1. grep

      grep -vFf badmails.txt my_email_list.txt > tempfile && 
        mv tempfile my_email_list.txt
      

      Here, you are giving grep a list of patterns (-f) to search for, telling it to treat them as simple strings (-F) and asking for those lines that do not (-v) match any of them. Finally, you redirect the output to a temporary file and then rename the file to overwrite the original.

    2. Perl

      perl -i -e 'open($f,"badmails.txt"); map{$k{$_}++}<$f>; 
                  while(<>){print unless defined($k{$_})}' my_email_list.txt 
      

      This opens badmails.txt, saves each line as the key to a hash, then runs through each line of my_email_list.txt (while(<>){}) and prints it unless the same line (email) was present in badmails.txt, that is unless the corresponding value is defined in the hash (print unless defined($k{$_}))

    3. sed and shell:

      while read badmail; do 
        sed -i sed -i "/$badmail/d" my_email_list.txt ;
      done < badmails.txt 
      

      or, use the shell to build the list of mails you want to delete, e.g. [email protected]\|[email protected] and pass that to sed:

      bad=$(while read b; do printf "%s\|" "$b"; done < badmails.txt|
            sed 's/\\|$//')
      sed -i "/$bad/d" my_email_list.txt 
      

  • Related Question

    shell - Replace filename with filepath with sed
  • Alex Kahn

    I want to replace the string

    /opt/local/lib/ruby/gems/1.8/gems/cucumber-0.3.99/lib/cucumber.rb

    with the string

    /opt/local/lib/ruby/gems/1.8/gems/cucumber-0.3.99/lib/

    on the command line, probably using sed. I can't for the life of me figure out the replacement regex to pass to sed. Or maybe sed isn't even the right tool for the job. Any help would be appreciated.


  • Related Answers
  • Marcin

    no need for sed:

    dirname /usr/local/bin/program

    will return /usr/local/bin