Como combinar espaços em branco no sed?

218

Como posso corresponder espaço em branco no sed? Nos meus dados, desejo corresponder a todos os três caracteres de espaço em branco subsequentes (espaço de tabulação) e substituí-los por 2 espaços. Como isso pode ser feito?

Peter Smit
fonte

Respostas:

226

A classe de caracteres \scorresponderá aos caracteres de espaço em branco <tab>e <space>.

Por exemplo:

$ sed -e "s/\s\{3,\}/  /g" inputFile

substituirá cada sequência de pelo menos três espaços em branco por dois espaços.


OBSERVAÇÃO : Para conformidade com POSIX, use a classe de caracteres em [[:space:]]vez de \s, pois a última é uma extensão GNU sed. Veja as especificações POSIX para sed e BREs

mrucci
fonte
5
aha! Foi o interruptor -e ausente que me pegou.
sequoia mcdowell
25
Eu também tive que adicionar a opção '-r', que permite que os regexs estendidos façam com que o sed reconheça '\ s' como espaço.
HUB 16/05
39
Com a Apple, sedeu tive que usar [[:space:]]porque \snão funcionou para mim. Talvez \sseja uma extensão GNU sed ?
Jared Beck
2
@JaredBeck graças, estava ficando sem ideias por que meu trabalho regex não era simples .. Esta é coxo, eu pensei \ s foi regex estendida padrão .. Também -r não funciona e -E fez agachamento
Karthik T
3
Em vez de [[:space:]um poderia usar o [[:blank:]]que corresponde apenas a abas horizontais e espaços (mas nenhuma nova linha, aba vertical etc.).
stefanct
67

Isso funciona no MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
algumas ideias
fonte
2
você sabe se isso funciona em todas as distros do Linux?
amphibient
2
Geralmente, o GNU sed não terá -E. Na página de manual do BSD sed: "As opções -E, -a e -i são extensões não padrão do FreeBSD e podem não estar disponíveis em outros sistemas operacionais."
Brad Koch
1
Por que você precisa do sinalizador -E para o operador +? A maioria das expressões provavelmente ficaria bem com *, então isso funcionaria em outras plataformas.
Samuel
5
@ Samuel Se você usar *, o regex corresponderá a zero ou mais espaços, e você terá um espaço entre cada caractere e um espaço em cada extremidade de cada linha. Se você não possui o sinalizador -E, deseja sed "s/[[:space:]]\+/ /g"corresponder a um ou mais espaços.
precisa saber é o seguinte
1
FWIW, o sed do NetBSD também suporta a -Ebandeira.
precisa
13

Algumas versões mais antigas do sed podem não reconhecer \ s como um símbolo de espaço em branco correspondente. Nesse caso, você pode combinar uma sequência de um ou mais espaços e tabulações com '[XZ] [XZ] *' onde X é um espaço e Z é uma tabulação.

Marnix A. van Ammers
fonte
1
Portanto, para a necessidade específica aqui, com um sed mais antigo, você pode fazer: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' arquivo de entrada em que X é uma guia e Z é um espaço.
Marnix A. van Ammers
10
sed 's/[ \t]*/"space or tab"/'
Zac
fonte
2
Isso garante que funcione em qualquer versão sedou sistema? Caso contrário, vale a pena mencionar onde isso funciona da mesma maneira que as outras respostas, apenas para conhecermos as limitações e onde isso pode não ter o resultado pretendido.
Mokubai
2
Este ER é o que eu uso para corresponder a espaço em branco. É mais simples que as classes de caracteres apenas para corresponder à tabulação ou espaço. Ele usa apenas as convenções mais básicas de expressões regulares, portanto, deve funcionar em qualquer lugar com uma implementação funcional de expressões regulares.
Nate
3
No Mac 10.9.5, isso corresponde a espaços e 't'. Eu usei o Michael Douma's acima para combinar caracteres de espaço em branco (ele também funciona com -e).
Alien Life Form
Não funciona sensivelmente no meu sistema SUSE. Corresponde ao primeiro lugar na linha em que há zero ou mais espaços, antes do primeiro caractere. Duvido que essa seja a função pretendida e certamente não foi o caso de uso solicitado. Eu acredito que você deseja alterar o '*' para '\ +' (ou '\ {3, \}' de acordo com a pergunta) e talvez colocar ag no final do comando sed para corresponder a todas as ocorrências do padrão. Substituir [\ t] por [[: space:]] também pode ser desejável, caso exista algo mais para espaço em branco na linha.
precisa saber é o seguinte