O problema de usar grep em nomes de arquivos é que grep é uma ferramenta orientada a linhas e nomes de arquivos podem conter novas linhas.
Supondo que todos os nomes de arquivos em seu arquivo não tenham novas linhas, use grep -v para negar a correspondência:
grep -iF -v 'iX500' <note_list
Eu adicionei -F , pois é uma string em vez de uma expressão regular com a qual estamos combinando.
O ^ é usado dentro de [...] para corresponder a um único caracter não em um determinado conjunto. Por exemplo, [^a-z] corresponderia a um único caractere que não é uma letra minúscula no intervalo fornecido (assumindo o código do idioma POSIX padrão). Quando usado em outro lugar, ^ denota o início da string, de modo que, por exemplo, ^alpha corresponde à string alpha somente no início de uma linha (e, da mesma forma, alpha$ corresponderia à string apenas no final da linha).
O que eu acho que você está procurando é criar uma expressão regular que corresponda a "não iX500 ". O problema é que a maioria das strings no seu exemplo corresponderia a isso. Por exemplo, o bit que é Applications (em ambas as linhas no exemplo) é "não iX500 ".
O seguinte extrai todas as linhas que não contêm a letra X :
grep '^[^X]*$'
Em vez da expressão "não X " [^X]* , no seu caso, você teria que criar uma expressão regular que corresponda a a linha inteira , mas que não corresponda à palavra iX500 em qualquer lugar.
Provavelmente é possível de alguma forma com o GNU grep e usando uma expressão PCRE com look-ahead / behind, mas é muito mais fácil corresponder apenas a iX500 e negar o sentido da correspondência com -v .