-2

#!/bin/bash

#!/bin/bash
while read email; do
    provider=$(echo $email | cut -d "@" -f 2)
    if [ ! -d $provder]; then
      mkdir $provider
    fi
    mv $email $provider
done < list.txt


 #bash sort.sh
sort.sh: line 8: syntax error near unexpected token `done'
'sort.sh: line 8: `done < list.txt
  • 1
    Paste your code into https://shellcheck.net Fix the errors you can. Come back and ask specific questions about the rest – roaima Dec 13 '22 at 01:38
  • From the error message, I'm pretty sure your script has DOS/Windows line endings, which cause all sorts of trouble. See ["Are shell scripts sensitive to encoding and line endings?"](https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings) (answer: yes, very). But you should also fix the things [shellcheck.net](https://shellcheck.net/) points out. – Gordon Davisson Dec 13 '22 at 02:57
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Dec 13 '22 at 08:03

1 Answers1

1

There are three obvious problems at first glance:

  1. Misspelled $provder on line 4
  2. Missing space between $provder and ] also on line 4
  3. Failure to double-quote your variables. See Why does my shell script choke on whitespace or other special characters?

and a fourth problem:

  1. Using a shell loop to process text. See Why is using a shell loop to process text considered bad practice?.

    Use awk or perl instead. Perl is probably the better choice as it mkdir and rename built-in, whereas you'd have to use system() to fork external programs mkdir and mv in awk. For example:

    perl -lne 'my ($username,$provider) = split /\@/;
    
               if (-e $provider) {
                 if (! -d $provider) {
                   warn "$provider exists but is not a directory";
                   next;
                 };
               } else {
                   mkdir $provider;
               };
    
               rename $_, "$provider/$_"' list.txt
    

    Alternatively, using the perl rename utility:

    rename 's/(.*)@(.*)/mkdir $2 || next; sprintf "%s\/%s", $2, $_/e' < list.txt
    
cas
  • 1
  • 7
  • 119
  • 185
  • 1
    I agree with the first three problems, but I don't think a shell loop is inappropriate here. Unless there are a huge number of email addresses, performance isn't likely to be an issue, and the perl and `rename` solutions aren't particularly more readable (they're actually much *less* readable to me, simply because I'm more familiar with bash than with perl that particular rename tool). – Gordon Davisson Dec 13 '22 at 03:05
  • shell's job is to co-ordinate the execution of other programs (e.g. grep, sed, cut, awk, perl, etc) to process text or other data, processing data with shell itself is almost always inappropriate. Performance isn't the only reason to use awk or perl or anything-that-isn't-shell. As for readability, it doesn't take too many uses of command substitution to do things that are built-in to other languages, or weird quoting contortions to work around shell's primary purpose of being an interactive command-line interpreter, to make a shell script ugly and difficult to read. – cas Dec 13 '22 at 03:49