Tengo los siguientes datos (una lista de paquetes R analizados desde un archivo Rmarkdown), que quiero convertir en una lista que puedo pasar a R para instalar:
d3heatmap
data.table
ggplot2
htmltools
htmlwidgets
metricsgraphics
networkD3
plotly
reshape2
scales
stringr
Quiero convertir la lista en una lista del formulario:
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Actualmente tengo una tubería de bash que va del archivo sin procesar a la lista anterior:
grep 'library(' Presentation.Rmd \
| grep -v '#' \
| cut -f2 -d\( \
| tr -d ')' \
| sort | uniq
Quiero agregar un paso para convertir las nuevas líneas en la lista separada por comas. He intentado agregar tr '\n' '","'
, que falla. También probé varias de las siguientes respuestas de desbordamiento de pila, que también fallan:
Esto produce library(stringr)))phics)
como resultado.
Esto produce ,%
como resultado.
Esta respuesta (con el -i
indicador eliminado) produce una salida idéntica a la entrada.
'
o"
.Respuestas:
Puede agregar comillas con sed y luego combinar líneas con pegar , así:
Si está ejecutando un sistema basado en GNU coreutils (es decir, Linux), puede omitir el seguimiento
'-'
.Si ingresa datos que tienen terminaciones de línea de estilo DOS (como sugirió @phk), puede modificar el comando de la siguiente manera:
fuente
sed 's/^\|$/"/g'|paste -sd, -
sed
:sed 's/.*/"&"/;:l;N;s/\n\(.*\)$/, "\1"/;tl'
paste
solo;)awk
: Alternativa con menos escape de shell y, por lo tanto, más legible: Salida: Explicación:La
Notaawk
secuencia de comandos en sí sin todo el escape esBEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Después de imprimir la primera entrada,p
se establece la variable (antes de eso es como una cadena vacía). Con esta variable,p
cada entrada (o enawk
-speak: record ) tiene el prefijo y además se imprime con comillas simples a su alrededor. Laawk
variable del separador de registro de salidaORS
no es necesaria (ya que el prefijo lo hace por usted), por lo que está configurada para estar vacía en elBEGIN
ing. Ah, y podríamos nuestro archivoEND
con una nueva línea (por ejemplo, funciona con otras herramientas de procesamiento de texto); en caso de que no sea necesaria la parte conEND
y todo lo que está después (dentro de las comillas simples) se puede eliminar.Si tiene finales de línea de estilo Windows / DOS (
\r\n
),\n
primero debe convertirlos al estilo UNIX ( ). Para hacer esto, puede ponertr -d '\015'
al principio de su tubería:(Suponiendo que no tiene ningún uso para
\r
s en su archivo. Suposición muy segura aquí).Alternativamente, simplemente ejecute
dos2unix /path/to/input.list
una vez para convertir el archivo en el lugar.fuente
', 'stringr23aphics
como la salida.print p"'"'"'"$0"'"'"'"; p=", "
—¡Santas citas, Batman!p"'\''"$0"'\''";
también habría funcionado (aunque no es POSIXy), o alternativamente usandobash
las cadenas de comillas C ($''
) incluso soloprint p"\'"$0"\'";
( aunque podría haber requerido duplicar otras barras invertidas), pero hay ya el otro método que usaawk
el carácter se escapa.Como muestra la respuesta vinculada de @ don_crissti , la opción de pegar limita con increíblemente rápido: la tubería del kernel de Linux es más eficiente de lo que hubiera creído si no lo hubiera probado. Sorprendentemente, si puede estar satisfecho con una coma que separa los elementos de su lista en lugar de una coma + espacio, una tubería de pegado
es más rápido que incluso un
flex
programa razonable (!)Pero si solo un rendimiento decente es aceptable (y si no está ejecutando una prueba de esfuerzo, no podrá medir las diferencias de factores constantes, todas son instantáneas) y desea flexibilidad con sus separadores y una razonable -liner-y-ness,
es tu boleto Sí, parece ruido de línea, pero el
H;1h;$!d;x
idioma es la forma correcta de sorber todo, una vez que puedes reconocer que todo se vuelve realmente fácil de leer, ess/.*/'&'/
seguido por un sorbo y uns/\n/, /g
.editar: bordeando lo absurdo, es bastante fácil obtener flexibilidad para vencer a todo lo demás hueco, solo dígale a stdio que no necesita la sincronización integrada multiproceso / controlador de señal:
y bajo estrés, es 2-3 veces más rápido que las tuberías de pasta, que son al menos 5 veces más rápidas que todo lo demás.
fuente
(paste -d\ \'\' /dev/null /dev/null - /dev/null | paste -sd, -) <infile | cut -c2-
haría coma + espacio @ más o menos la misma velocidad, aunque como notó, no es realmente flexible si necesita una cadena elegante como separadorflex
cosas son bastante buenas, hombre ... esta es la primera vez que veo a alguien publicarflex
código en este sitio ... ¡gran voto! Por favor, publique más de estas cosas.Perl
Python one-liner:
Funciona de manera simple: redirigimos input.txt a stdin usando el
<
operador de shell , leemos cada línea en una lista.strip()
eliminando nuevas líneas yrepr()
creando una representación entre comillas de cada línea. La lista se une en una gran cadena a través de la.join()
función, con un,
separadorAlternativamente, podríamos usar
+
para concatenar comillas a cada línea despojada.Perl
Esencialmente, es la misma idea que antes: lea todas las líneas, elimine la nueva línea final, encierre entre comillas simples, coloque todo en array @cvs e imprima los valores de matriz unidos con comas.
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scale', 'stringr'
fuente
join
deberían ser capaces de tomar un iterador, por lo tanto, no debería haber necesidad de materializar el ciclo stdin en una listaCreo que lo siguiente debería funcionar bien, suponiendo que sus datos estén en el texto del archivo
Usemos matrices que tienen la sustitución en frío:
El resultado del script debe ser el siguiente:
Creo que esto era lo que estabas buscando?
fuente
bash
y si bien es seguro suponer que alguien podría usarlo (después de todo AFAIK es el shell más utilizado), aún no se debe dar por sentado. Además, hay partes que podría hacer para un mejor trabajo al citar (poner comillas dobles). Por ejemplo, aunque es improbable que los nombres de los paquetes tengan espacios, sigue siendo una buena convención citar variables en lugar de no, es posible que desee ejecutar shellcheck.net sobre él y ver las notas y explicaciones allí.A menudo tengo un escenario muy similar: copio una columna de Excel y quiero convertir el contenido en una lista separada por comas (para su uso posterior en una consulta SQL como
... WHERE col_name IN <comma-separated-list-here>
).Esto es lo que tengo en mi .bashrc:
Luego ejecuto
lbl
("línea por línea") en la línea cmd que espera la entrada, pego el contenido del portapapeles, presiono<C-D>
y la función devuelve la entrada rodeada()
. Esto se ve así:(No recuerdo por qué puse el dos2unix aquí, presumiblemente porque esto a menudo causa problemas en la configuración de mi empresa).
fuente
Algunas versiones de sed actúan un poco diferente, pero en mi Mac, puedo manejar todo menos el "uniq" en sed:
Desafortunadamente para arreglar la parte única, tienes que hacer algo como:
--Pablo
fuente
Es curioso que para usar una lista de texto simple de paquetes R para instalarlos en R, nadie haya propuesto una solución usando esa lista directamente en R, pero pelee con bash, perl, python, awk, sed o lo que sea para poner comillas y comillas en el lista. Esto no es necesario en absoluto y además no resuelve cómo ingresar y usar la lista transformada en R.
Simplemente puede cargar el archivo de texto sin formato (dicho,
packages.txt
) como un marco de datos con una sola variable, que puede extraer como un vector, directamente utilizable porinstall.packages
. Entonces, conviértalo en un objeto R utilizable e instale esa lista es solo:O sin un archivo externo:
fuente