0

I extracted some digits from files using grep, assuming they are 1 2 3 5 6 11 18. To get the missings ones in 1..20, I put them into files and compare using comm.

a='1 2 3 5 6 11 18'
printf '%d\n' $a | sort -u > 111
printf '%d\n' {1..20} | sort -u > 222
comm 111 222
rm 111 222

which outputs

    1
10
    11
12
13
14
15
16
17
    18
19
    2
20
    3
4
    5
    6
7
8
9

Is there more convenient way without saving to files?

wsdzbm
  • 3,096
  • 3
  • 25
  • 28
  • [Process substitution](http://mywiki.wooledge.org/ProcessSubstitution) : `comm <(printf '%d\n' $a | sort -u) <(printf '%d\n' {1..20})` Side note: for second case `{1..20}`, you don't need sort; they are already sorted. – anishsane Jun 15 '16 at 16:42
  • ^^ Having said that, a pure bash variant can be written easily: `a='1 2 3 5 6 11 18'; for x in $a; do t[$x]=1; done; for((x=1;x<=20;x++)); do ((t[i])) || echo $i; done` – anishsane Jun 15 '16 at 16:49
  • Thanks @anishsane . But the 2nd one outputs null lines. The 1st one needs `sort`. `1 2 3 4 ... 10 ...20` is not deemed as sorted, but `1 10 11 ... 2 20 3 ...` does. – wsdzbm Jun 15 '16 at 17:31
  • ^^ My bad... for the first one, use `sort -un` instead of just `sort -u` – anishsane Jun 16 '16 at 03:31

1 Answers1

3

You can iterate over the numbers from 1 though 20, and then use a regex to compare each number against a:

a='1 2 3 5 6 11 18'
for i in {1..20}; do
  re="\\b$i\\b"
  [[ "$a" =~ $re ]] || echo "$i"
done

The regex is quite simple: \b is a word boundary, and $i gets expanded to 1, 2, ..., 20

The above will print all numbers that are not in a.

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Hi @andlrc it works but I have no idea why two backslashes not just one? and why `[[ "$a" =~ "\\b$i\\b" ]] || echo "$i"` doesn't work – wsdzbm Jun 15 '16 at 17:35
  • 1
    In theory `"\b"` should work but since backslash is an escape character we need to escape it: `\\b` -> `\b`, or put it in single quotes: `'\b'"$i"'\b'`. For why `[[ "$a" =~ "\\b$i\\b" ]]` doesn't work: It seems to be a bug in bash, there is an explanation here: [does bash support word boundary regular expressions?](http://stackoverflow.com/a/12696899/887539) – Andreas Louv Jun 15 '16 at 17:48