Question: I am in a folder with lots of `.txt` file, I would like to find all the files which contain both `stringA` and `stringB` (not necessarily on the same line), then list these files in the order of the size (from small to big)

I have tried the follows, but it doesn't work:

```
ls -lS | for f in *; do grep -q stringA $f && grep -l stringB $f; done

```

Does anyone have a good idea?

Answer: 
Using [perl](/questions/tagged/perl "show questions tagged 'perl'") (portable and no problem with space in filenames) :

```
perl -Mautodie -wle '
    for (<"*.txt">) {
        open my $fh, "<", $_;
        my @list = <$fh>;
        close $fh;
        if (grep { /stringA/ } @list and grep { /stringB/ } @list) {
            $h->{$_}->{size} = (stat($_))[8];
        }
    }
    END{
        print join "\n", sort { $h->{$a}->{size} <=> $h->{$b}->{size} } keys %$h;
    }
'

```
```
 egrep -l '(stringA|stringB)' * | xargs ls -1S

```

`egrep` allows for regular expressions, so the above will search for stringA OR stringB in all files, the `-l` option tells egrep to just output the files matched (and supress the output of the matching lines). Piping it to `xargs ls -1S` will pass all the files matches to `ls -1S`. `-1` tells ls to list one file per line and `-S` tells ls to sort by file size rather than by name.

**EDIT** Oops that's an OR (misread of the question).

In which case an adaption of sputnick's solution to use two greps

```
grep -l stringA * | xargs grep -l stringB | xargs -ls -1S

```

(at least getting around `du` and `sort` there's one less process :)