Corresponder caractere ou fim de linha com sed

1

Tentando limpar uma variável PYTHONPATH que possui a sintaxe comum:

/a/path:/another/path/:/one/more/path

Desejo remover todos os caminhos que começam com /mnt . Primeiro, tente com sed :

sed 's,/mnt/[^:]\+:,,g' <<< $PYTHONPATH

Remove todas as ocorrências que começam com /mnt/ , seguidas por um ou mais caracteres, exceto dois pontos, e o caractere de dois pontos subsequente.

Isso, no entanto, falhará no seguinte exemplo:

PYTHONPATH="/mnt/first/path:/mnt/second/path"

porque o segundo caminho não termina com dois pontos. Eu não pude dar à luz nada melhor do que fazer outra pesquisa com uma condição ligeiramente diferente:

sed 's,/mnt/[^:]\+:,,g;s,/mnt/.*$,,g' <<< $PYTHONPATH

Agora, depois que todas as ocorrências terminadas com dois pontos forem removidas, outra execução remove todas as ocorrências (na verdade, há no máximo uma) que começam com /mnt/ e terminam com o final da string.

Perguntas:

  1. Para a tarefa, esta é uma solução aceitável?
  2. Existe um caso especial em que a solução acima irá falhar?
  3. Uma solução de pesquisa única é possível aqui? Apenas curioso.

Obrigado antecipadamente!

    
por hoefling 25.08.2016 / 20:24

3 respostas

2

Como apontado pelos Argonauts, você pode fazer isso em uma linha com a instrução OR. Você não precisa necessariamente usar a opção -r , mas o comando sed será um pouco mais complexo, já que você tem que escapar dos parênteses e barar da seguinte forma:

sed 's,/mnt/[^:]\+\(:\|$\),,g' <<< "$PYTHONPATH"

Note que é uma boa prática citar variáveis no bash.

    
por 26.08.2016 / 06:40
1

O que você tem é aceitável, mas uma saída ainda mais fácil e mais preguiçosa é:

Basta criar uma nova variável

NEWVAR="${PYTHONPATH}:"
sed 's,/mnt/[^:]\+:,,g' <<< $NEWVAR

Supondo que você esteja atribuindo isso a uma variável e queira que os dois-pontos sejam aparados novamente, com a manipulação da variável bash, você pode fazer isso:

newvar="${PYTHONPATH}:"
nomnt=$( sed 's,/mnt/[^:]\+:,,g' <<< $newvar )
nomnt=${nomnt%%:}
echo ${nomnt}

Ou em todo o sed:

sed 's,/mnt/[^:]\+:,,g;s/:$//;' <<< "${PYTHONPATH}:"
    
por 25.08.2016 / 20:43
1

Você pode usar expressões regulares estendidas com sed para simplificar um pouco as coisas:

sed -r 's,/mnt/[^:]+(:|$),,g' <<< $PYTHONPATH

O -r indica o uso de uma regex estendida, que nesse caso é a instrução OR (:|$) , fazendo com que ela termine a correspondência de padrão em dois-pontos ou no final da linha.

Nota: com as versões OS X e BSD do sed, use -E em vez de -r

E, embora seja provavelmente óbvio, se você estiver tentando atualizar o próprio PYTHONPATH, precisará atribuir o valor depois de remover as entradas / mnt / *:

export PYTHONPATH=$(sed -r 's,/mnt/[^:]+(:|$),,g' <<< $PYTHONPATH)
    
por 26.08.2016 / 03:14