Como inserir uma nova linha antes de um padrão em uma linha?
Por exemplo, isso inserirá uma nova linha atrás do padrão regex.
sed 's/regex/&\n/g'
Como posso fazer o mesmo, mas na frente do padrão?
Dado esse arquivo de entrada de amostra, o padrão para combinar é o número de telefone.
some text (012)345-6789
Deve se tornar
some text
(012)345-6789
sed '/regex/G'
Respostas:
Isso funciona
bash
e ézsh
testado no Linux e OS X:Em geral, para
$
seguido por uma string literal entre aspas simplesbash
realiza a substituição da barra invertida no estilo C, por exemplo,$'\t'
é traduzida para uma guia literal. Além disso, o sed deseja que seu literal de nova linha seja escapado com uma barra invertida, daí o\
anterior$
. E, finalmente, o próprio sinal de cifrão não deve ser citado para que seja interpretado pelo shell; portanto, fechamos a cotação antes da$
e depois a abrimos novamente.Edit : Como sugerido nos comentários por @ mklement0, isso também funciona:
O que acontece aqui é: todo o comando sed agora é uma string no estilo C, o que significa que a barra invertida que o sed precisa ser colocada antes que a nova linha literal agora seja escapada com outra barra invertida. Embora seja mais legível, nesse caso, você não poderá fazer substituições de string de shell (sem torná-lo feio novamente).
fonte
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
. Observe as duas aspas simples após o \ n. O primeiro fecha a$
seção " " para que o restante da linha não seja afetado por ele. Sem essas aspas, o \ 2 foi ignorado.sed $'s/regexp/\\\n/g'
, o que melhora a legibilidade - a única ressalva é que você precisa então de dobrar todos os literais\
caracteres.Algumas das outras respostas não funcionaram na minha versão do sed. Mudar a posição
&
e\n
funcionou.Editar: parece não funcionar no OS X, a menos que você instale
gnu-sed
.fonte
brew install gnu-sed
seguido porgsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
No sed, você não pode adicionar novas linhas no fluxo de saída com facilidade. Você precisa usar uma linha de continuação, o que é estranho, mas funciona:
Exemplo:
Veja aqui para detalhes. Se você quiser algo um pouco menos estranho, tente usar
perl -pe
com grupos de correspondência em vez de sed:$1
refere-se ao primeiro grupo correspondente na expressão regular, onde os grupos estão entre parênteses.fonte
perl -pi -e 's/(.*)/\n$1/' foo
s
chamada de função (ao contrário da implementação GNU Sed, que faz) . A resposta acima funciona com ambas as implementações; para uma visão geral de todas as diferenças, veja aqui .No meu mac, o seguinte insere um único 'n' em vez de nova linha:
Isso substitui a nova linha:
fonte
sed -i '' -e ...
e estava tendo problemas com um^M
cursor M (ctrl + m) sendo gravado no arquivo. Acabei usando perl com os mesmos parâmetros.\n
).echo...
e nova linha) que eu fiz isso no vim.sed "s/regexp/`echo`/g"
- o que irá produzir um único LF vez de LF-CR`echo`
resultará na string vazia , porque as substituições de comandos invariavelmente cortam todas as novas linhas à direita. Não há como usar uma substituição de comando para inserir diretamente uma única nova linha (e inserir\n\r
- isto é, um CR adicional - é uma péssima idéia).fonte
$'\n'
está contando com o shell para gerar a nova linha. Tais soluções podem não ser portáteis. Esta está. Claro, também é uma duplicata do segundo exemplo na resposta do tgamblin de 2009.Nesse caso, eu não uso sed. Eu uso tr.
Isso pega a vírgula e a substitui pelo retorno de carro.
fonte
cat Somefile | tr ',' '\n'
YMMVVocê pode usar one-liners perl da mesma forma que o sed, com a vantagem da expressão regular completa do perl suporte (que é muito mais poderoso do que o obtido com o sed). Também há muito pouca variação entre as plataformas * nix - o perl geralmente é o perl. Portanto, você pode parar de se preocupar em como fazer com que a versão do sed do seu sistema específico faça o que você deseja.
Nesse caso, você pode fazer
-pe
coloca o perl em um loop "execute and print", bem como o modo normal de operação do sed.'
cita todo o resto para que o shell não interfira()
ao redor do regex é um operador de agrupamento.$1
no lado direito da substituição, imprime o que foi encontrado dentro desses parênteses.Finalmente,
\n
é uma nova linha.Independentemente de você estar usando parênteses como um operador de agrupamento, você precisa escapar dos parênteses que está tentando corresponder. Portanto, uma regex para corresponder ao padrão listado acima seria algo como
\(
ou\)
corresponde a um paren literal e\d
corresponde a um dígito.Melhor:
Eu imagino que você possa descobrir o que os números nos aparelhos estão fazendo.
Além disso, você pode usar delimitadores diferentes de / para seu regex. Portanto, se você precisar corresponder / não precisará escapar dela. Qualquer uma das opções abaixo é equivalente à regex no início da minha resposta. Em teoria, você pode substituir qualquer caractere pelos padrões.
Algumas considerações finais.
usando em
-ne
vez de-pe
agir da mesma forma, mas não é impresso automaticamente no final. Pode ser útil se você quiser imprimir sozinho. Por exemplo, aqui está um grep-alike (m/foobar/
é uma correspondência de regex):Se você acha que lidar com novas linhas é problemático e deseja que ele seja tratado magicamente por você, adicione
-l
. Não é útil para o OP, que estava trabalhando com novas linhas, no entanto.Dica de bônus - se você tiver o pacote pcre instalado, ele vem com ele
pcregrep
, que usa expressões regulares compatíveis com perl.fonte
Hmm, as novas linhas que escaparam parecem funcionar em versões mais recentes do
sed
(eu tenho o GNU sed 4.2.1),fonte
funcionou bem no El Captitan com o
()
apoiofonte
Para inserir uma nova linha no fluxo de saída no Linux, usei:
Onde
file1
estava:Antes da substituição no local sed e:
Após a substituição no local sed. Observe o uso de
\\\n
. Se os padrões tiverem um"
interior, escape usando\"
.fonte
sed
insere em\n
vez de LF porque obtém\\n
o parâmetro do shell. --- Este código funciona:sed -i "s/def/abc\ndef/" file1
. ---GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(versão do CentOS 6.4 / Ubuntu 12.04.3).no sed, você pode fazer referência a grupos no seu padrão com "\ 1", "\ 2", .... portanto, se o padrão que você procura é "PATTERN" e deseja inserir "ANTES" na frente dele , você pode usar, sem escapar
ie
fonte
Você também pode fazer isso com o awk, usando
-v
para fornecer o padrão:Isso verifica se uma linha contém um determinado padrão. Nesse caso, ele anexa uma nova linha ao início.
Veja um exemplo básico:
Observe que isso afetará todos os padrões em uma linha:
fonte
1
é usado no Awk como uma abreviação de{print $0}
. O motivo é que qualquer condição avaliada como True dispara a ação padrão do Awk, que consiste em imprimir o registro atual.Isso funciona no MAC para mim
Dono, se é o perfeito ...
fonte
Depois de ler todas as respostas para essa pergunta, ainda me levou muitas tentativas para obter a sintaxe correta para o seguinte script de exemplo:
O script anexa uma nova linha
\n
seguida por outra linha de texto ao final de um arquivo usando um únicosed
comando.fonte
\ 0 é nulo; portanto, sua expressão é substituída por nulo (nada) e depois ...
\ n é a nova linha
Em alguns sabores do Unix não funciona, mas acho que é a solução para o seu problema.
fonte
No vi da Red Hat, eu pude inserir retornos de carro usando apenas o caractere \ r. Acredito que isso execute internamente 'ex' em vez de 'sed', mas é semelhante e o vi pode ser outra maneira de fazer edições em massa, como patches de código. Por exemplo. Estou cercando um termo de pesquisa com uma instrução if que insiste em retornos de carro após as chaves:
Observe que eu também pedi para inserir algumas guias para melhorar o alinhamento das coisas.
fonte