Remover palavras compostas de letras maiúsculas e minúsculas?

3

Eu tenho um arquivo chamado file.txt . Neste arquivo existem palavras compostas de letras maiúsculas e minúsculas, também existem palavras consistem em letras maiúsculas ou minúsculas e números. Eu gostaria de filtrar este arquivo, então a saída está livre das palavras que contêm ambas letras maiúsculas e minúsculas. Por exemplo, a entrada file.txt :

Aaa
aBb
aB
Aa12
12aA
123
123Ab
AAA
aaa

Neste arquivo, há palavras com letras maiúsculas e minúsculas (por exemplo, Aaa, aBp) e as palavras contêm letras maiúsculas e minúsculas AND dígitos (por exemplo, 123Ab). Além disso, as palavras contêm apenas letras pequenas (por exemplo, aaa) ou apenas letras maiúsculas (por exemplo, AAA). Gostaria de remover apenas as palavras que contêm letras minúsculas AND (por exemplo, Aaa, aBp), portanto, a saída é a seguinte:

Aa12
12aA
123
123Ab
AAA
aaa

Alguma idéia?

    
por Ahmed 21.09.2018 / 00:22

4 respostas

5
grep -Exv '[A-Za-z]*([A-Z][a-z]|[a-z][A-Z])[A-Za-z]*'

Explicação

  • A ideia é combinar o oposto do que você deseja primeiro, ou seja, aquelas linhas que contêm apenas letras maiúsculas e minúsculas. Isso usa grep -Ex , ou seja, grep com regex estendido, corresponde à linha inteira. O sinal -v , em seguida, nega o regex, ou seja, retorna as linhas que não correspondem ao seguinte regex.
  • A parte central ([A-Z][a-z]|[a-z][A-Z]) corresponde a uma única letra maiúscula seguida por uma letra minúscula ou vice-versa.
  • A parte externa [A-Za-z]*...[A-Za-z]* significa que o restante da linha deve conter apenas letras maiúsculas ou minúsculas.
por 21.09.2018 / 00:31
1

Para reafirmar seus requisitos, você precisa manter uma palavra se:

  • contém um dígito sem letra ou
  • são todas letras maiúsculas ou
  • são todas as letras minúsculas

Então

awk '/[^[:alpha:]]/ || /^[[:upper:]]+$/ || /^[[:lower:]]+$/' file
    
por 29.09.2018 / 17:55
1

Usando sed :

$ sed -E -e '/[0-9]/b' -e '/^[A-Z]+$/b' -e '/^[a-z]+$/b' -e 'd' <file
Aa12
12aA
123
123Ab
AAA
aaa

Script sed anotado:

/[0-9]/b        # Digits are present, branch to end
/^[A-Z]+$/b     # Only uppercase characters present, branch to end
/^[a-z]+$/b     # Only lowercase characters present, branch to end
d               # Delete line, start next cycle
                # (at end, implicit print)

Alternativamente,

sed -E -e '/[[:digit:]]/b' -e '/^[[:upper:]]+$/b' -e '/^[[:lower:]]+$/b' -e 'd' <file

Pode haver uma diferença entre este e o primeiro script sed , dependendo da sua localidade.

    
por 30.09.2018 / 14:01
1

Com grep e assumindo uma palavra por linha:

grep -E '[[:digit:]]|^([[:lower:]]+|[[:upper:]]+)$'

Para relatar todas as palavras correspondentes em um texto, com potencialmente várias palavras por linha, palavras delimitadas por caracteres que não são de palavras:

<text tr -cs '[:alnum:][:digit:]_' '[\n*]' |
  grep -E '[[:digit:]]|^([[:lower:]]+|[[:upper:]]+)$'

Note que você precisa de uma implementação tr compatível com POSIX, o GNU tr não fará. Nos sistemas GNU, você pode usar sed :

<text sed -E 's/\W+/\n/g' |
  grep -E '[[:digit:]]|^([[:lower:]]+|[[:upper:]]+)$'
    
por 30.09.2018 / 18:20