Por que esse trabalho de substituição de regex não funciona?

1

Eu tenho um arquivo no seguinte formato:

$ cat myfile     
12 42956    Cinema - 3D/Multiplex    
7  12560    Status Update    
5  184   Movie  

Eu estou tentando adicionar aspas duplas à descrição do texto.
Não consigo entender por que o seguinte regex não funciona:
$ sed -E 's/\b[0-9]+\b\s*\b[0-9]+\b\s*([^\s]+)/""/g' myfile

Minha pergunta é sobre especificamente esta regex e não outra abordagem para fazer a mesma coisa. Eu

    
por Jim 09.02.2017 / 21:24

3 respostas

3

Até onde eu sei, \s é uma expressão regular em Perl que é igual a [[:blank:]] em sed . Dentro de [ ... ] , \s significa "um \ e um s ". Observe também que, mesmo que [^\s]+ fosse igual a [^␣]+ , isso não teria correspondido a Status Update devido ao espaço intermediário.

A substituição substituirá toda a correspondência com o primeiro grupo entre aspas duplas. Você provavelmente quer pegar todas as três colunas ou você acabará com somente a última coluna. E, como você está tentando corresponder a linha inteira, você deve ancorar a expressão no começo e no final com ^ e $ e descartar a g no final.

Alternativa:

$ sed -E 's/[[:alpha:]].+/"&"/' myfile
12 42956    "Cinema - 3D/Multiplex    "
7  12560    "Status Update    "
5  184   "Movie  "

Isso localizará a última coluna pelo fato de que seus dados parecem sempre começar com um não dígito. A expressão simplesmente corresponderá ao restante da linha do primeiro caractere alfabético e substituirá toda a correspondência por uma versão com aspas duplas da correspondência.

Os dados da questão tinham espaços no final e as aspas incluiriam esses. Para evitar os espaços no final:

$ sed -E -e 's/[[:blank:]]*$//' -e 's/[[:alpha:]].+/"&"/' myfile
12 42956    "Cinema - 3D/Multiplex"
7  12560    "Status Update"
5  184   "Movie"

Alternativamente,

while read -r a b c; do printf '%d\t%d\t"%s"\n' "$a" "$b" "$c"; done <myfile
12      42956   "Cinema - 3D/Multiplex"
7       12560   "Status Update"
5       184     "Movie"
    
por 09.02.2017 / 21:54
0
sed -E 's/\b([0-9]+\b\s*\b[0-9]+)\b\s*([^\s]+)/ ""/g' myfile

Isso adiciona apenas aspas duplas ao redor do texto.

Salvando os dígitos e espaços em um grupo e a string em outro grupo (\ 2), o sed gera o grupo 1 (\ 1) seguido por um espaço seguido por uma aspa dupla seguida pelo segundo grupo (\ 2 ) seguido da aspa dupla final.

Você pode reduzir isso um pouco agrupando todos os dígitos e espaços em um grupo ([0-9, ]*) e qualquer coisa depois de dígitos em outro grupo (.+) .

Isso dá:

sed -E 's/([0-9, ]*)(.+)/ ""/g' myfile
12 42956     "Cinema - 3D/Multiplex"
7  12560     "Status Update"
5  184    "Movie"
    
por 09.02.2017 / 22:28
0

Porque o Mac OSX sed não suporta \s . Apenas GNU sed suporta \s .

No Mac OSX, \s não funciona, mesmo com as cotações $'' ANSI-C.

$ echo $'1\t2 3' | sed 's/\s//g'
1   2 3
$ echo $'1\t2 3' | sed $'s/\s//g'
1   2 3

Em vez disso, você pode usar [[:space:]]

$ echo $'1\t2 3' | sed 's/[[:space:]]//g'
123

Ou você pode usar [ \t] , mas precisará da citação $'' ANSI-C para o caractere de tabulação.

$ echo $'1\t2 3' | sed $'s/[ \t]//g'
123
    
por 01.09.2017 / 01:09