Tenho os seguintes dados (uma lista de pacotes R analisados a partir de um arquivo Rmarkdown), que desejo transformar em uma lista que posso passar para o R para instalar:
d3heatmap
data.table
ggplot2
htmltools
htmlwidgets
metricsgraphics
networkD3
plotly
reshape2
scales
stringr
Quero transformar a lista em uma lista do formulário:
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Atualmente, tenho um pipeline de bash que vai do arquivo bruto para a lista acima:
grep 'library(' Presentation.Rmd \
| grep -v '#' \
| cut -f2 -d\( \
| tr -d ')' \
| sort | uniq
Quero adicionar uma etapa para transformar as novas linhas na lista separada por vírgula. Eu tentei adicionar tr '\n' '","'
, o que falha. Eu também tentei várias das seguintes respostas de estouro de pilha, que também falham:
Isso produz library(stringr)))phics)
como resultado.
Isso produz ,%
como resultado.
Esta resposta (com o -i
sinalizador removido) produz saída idêntica à entrada.
'
ou"
.Respostas:
Você pode adicionar aspas com sed e mesclar linhas com colar , assim:
Se você estiver executando um sistema baseado em coreutils GNU (ou seja, Linux), poderá omitir o final
'-'
.Se você inserir dados com terminações de linha no estilo DOS (como @phk sugeriu), poderá modificar o comando da seguinte maneira:
fonte
sed 's/^\|$/"/g'|paste -sd, -
sed
:sed 's/.*/"&"/;:l;N;s/\n\(.*\)$/, "\1"/;tl'
paste
só;)awk
: Alternativa com menos escape de shell e, portanto, mais legível: Resultado: Explicação:O
Notaawk
script em si sem todo o escape éBEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Depois de imprimir a primeira entrada, a variávelp
é definida (antes disso, é como uma string vazia). Com essa variável,p
cada entrada (ou inawk
-speak: record ) é prefixada e adicionalmente impressa com aspas simples. Aawk
variável separadora do registro de saídaORS
não é necessária (já que o prefixo está fazendo isso por você), portanto, ela deve estar vazia no momentoBEGIN
. Ah, e podemos usar nosso arquivoEND
com uma nova linha (por exemplo, para que funcione com outras ferramentas de processamento de texto); caso isso não seja necessário, a parte comEND
e tudo o que está depois (dentro das aspas simples) pode ser removido.Se você possui terminações de linha no estilo Windows / DOS (
\r\n
), primeiro é necessário convertê-las para o estilo UNIX (\n
). Para fazer isso, você pode colocartr -d '\015'
no início do seu pipeline:(Supondo que você não tenha utilidade para
\r
s no seu arquivo. Pressuposto muito seguro aqui.)Como alternativa, basta executar
dos2unix /path/to/input.list
uma vez para converter o arquivo no local.fonte
', 'stringr23aphics
como saída.print p"'"'"'"$0"'"'"'"; p=", "
- citações sagradas, Batman!p"'\''"$0"'\''";
também funcionaria (embora não seja POSIXy) ou, alternativamente, usandobash
as seqüências de citação C de C ($''
) mesmo que apenasprint p"\'"$0"\'";
(pode ser necessário duplicar outras barras invertidas), mas há já o outro método usandoawk
o caractere de escape.Como mostra a resposta vinculada de @ don_crissti , a opção de colar é incrivelmente rápida - a tubulação do kernel do linux é mais eficiente do que eu pensaria se não tivesse tentado agora. Notavelmente, se você puder ficar feliz com uma única vírgula separando os itens da lista em vez de uma vírgula + espaço, um pipeline de colagem
é mais rápido que um
flex
programa razoável (!)Mas se apenas um desempenho decente for aceitável (e se você não estiver executando um teste de estresse, não poderá medir diferenças de fator constante, são todos instantâneos) e deseja flexibilidade com seus separadores e um razoável -liner-y-ness,
é o seu bilhete. Sim, parece ruído de linha, mas o
H;1h;$!d;x
idioma é o caminho certo para absorver tudo, uma vez que você pode reconhecer que a coisa toda fica realmente fácil de ler, és/.*/'&'/
seguida por um slurp e as/\n/, /g
.edit: contornando o absurdo, é bastante fácil usar o flex para superar tudo o mais, basta dizer ao stdio que você não precisa da sincronização multithread / signalhandler integrada:
e sob estresse 2-3 vezes mais rápido que os pipelines de pasta, que são pelo menos cinco vezes mais rápidos que tudo o resto.
fonte
(paste -d\ \'\' /dev/null /dev/null - /dev/null | paste -sd, -) <infile | cut -c2-
faria vírgula espaço + @ praticamente a mesma velocidade embora, como você observou, não é realmente flexível, se você precisar de alguma seqüência de fantasia como separadorflex
material é bem legal, cara ... esta é a primeira vez que vejo alguém postandoflex
código neste site ... grande votação! Poste mais dessas coisas.Perl
One-liner do Python:
Funciona de maneira simples - redirecionamos input.txt para o stdin usando o
<
operador do shell , lemos cada linha em uma lista com a.strip()
remoção de novas linhas e arepr()
criação de uma representação entre aspas de cada linha. A lista é então unida em uma grande sequência via.join()
função, com,
o separadorComo alternativa, poderíamos usar
+
para concatenar aspas para cada linha despojada.Perl
Essencialmente, a mesma idéia de antes: leia todas as linhas, descasque a nova linha, coloque aspas simples, coloque tudo em array @cvs e imprima os valores da matriz unidos por vírgulas.
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'remodelar2', 'escalas', 'stringr'
fonte
join
devem ser capazes de levar um iterador, portanto, não há necessidade de materializar o loop stdin em uma listaEu acho que o seguinte deve funcionar muito bem, supondo que seus dados estejam no texto do arquivo
Vamos usar matrizes que têm a substituição no frio:
A saída do script deve ser a seguinte:
Eu acredito que era isso que você estava procurando?
fonte
bash
e embora seja seguro supor que alguém possa usá-lo (afinal o AFAIK é o shell mais usado), ele ainda não deve ser tomado como garantido. Além disso, existem partes em que você poderia fazer um trabalho melhor ao citar (colocar aspas duplas). Por exemplo, embora seja improvável que os nomes dos pacotes tenham espaços neles, ainda é uma boa convenção citar variáveis em vez de não, você pode executar o shellcheck.net sobre ele e ver as notas e explicações nele.Muitas vezes, tenho um cenário muito semelhante: copio uma coluna do Excel e quero converter o conteúdo em uma lista separada por vírgula (para uso posterior em uma consulta SQL como
... WHERE col_name IN <comma-separated-list-here>
).Isto é o que eu tenho no meu .bashrc:
Em seguida, corro
lbl
("linha por linha") na linha cmd que aguarda a entrada, colo o conteúdo da área de transferência, pressione<C-D>
e a função retorna a entrada cercada()
. Parece assim:(Não me lembro por que coloquei o dos2unix aqui, provavelmente porque isso geralmente causa problemas na configuração da minha empresa.)
fonte
Algumas versões do sed agem um pouco diferente, mas no meu mac, eu posso lidar com tudo, exceto o "uniq" no sed:
Infelizmente, para corrigir a parte única, é necessário fazer algo como:
--Paulo
fonte
É engraçado que, para usar uma lista em texto sem formatação de pacotes R para instalá-los no R, ninguém propôs uma solução usando essa lista diretamente no R, mas lute com bash, perl, python, awk, sed ou o que quer que seja para colocar aspas e vírgulas no Lista. Isso não é necessário e, além disso, não resolve como a entrada e o uso da lista transformada em R.
Você pode simplesmente carregar o arquivo de texto sem formatação (dito
packages.txt
) como um quadro de dados com uma única variável, que você pode extrair como um vetor, diretamente utilizávelinstall.packages
. Portanto, converta-o em um objeto R utilizável e instale essa lista:Ou sem um arquivo externo:
fonte