Saya memiliki data berikut (daftar paket R yang diuraikan dari file Rmarkdown), yang ingin saya ubah menjadi daftar yang dapat saya sampaikan kepada R untuk diinstal:
d3heatmap
data.table
ggplot2
htmltools
htmlwidgets
metricsgraphics
networkD3
plotly
reshape2
scales
stringr
Saya ingin mengubah daftar menjadi daftar formulir:
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Saat ini saya memiliki pipa bash yang beralih dari file mentah ke daftar di atas:
grep 'library(' Presentation.Rmd \
| grep -v '#' \
| cut -f2 -d\( \
| tr -d ')' \
| sort | uniq
Saya ingin menambahkan langkah untuk mengubah baris baru ke daftar yang dipisahkan koma. Saya sudah mencoba menambahkan tr '\n' '","'
, yang gagal. Saya juga mencoba sejumlah jawaban Stack Overflow berikut, yang juga gagal:
Ini menghasilkan library(stringr)))phics)
sebagai hasilnya.
Ini menghasilkan ,%
sebagai hasilnya.
Jawaban ini (dengan menghilangkan -i
flag), menghasilkan output yang identik dengan input.
'
atau"
.Jawaban:
Anda dapat menambahkan kutipan dengan sed dan kemudian menggabungkan garis dengan tempel , seperti itu:
Jika Anda menjalankan sistem berbasis GNU coreutils (yaitu Linux), Anda dapat menghilangkan trailing
'-'
.Jika Anda memasukkan data yang memiliki akhiran garis gaya-DOS (seperti yang disarankan @phk), Anda dapat memodifikasi perintah sebagai berikut:
sumber
sed 's/^\|$/"/g'|paste -sd, -
sed
sendirian:sed 's/.*/"&"/;:l;N;s/\n\(.*\)$/, "\1"/;tl'
paste
sendiri;)awk
: Alternatif dengan lebih sedikit shell yang keluar dan karenanya lebih mudah dibaca: Keluaran: Penjelasan:The
Catatanawk
Script itu sendiri tanpa semua melarikan diri adalahBEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Setelah mencetak entri pertama variabelp
ditetapkan (sebelum itu seperti string kosong). Dengan variabel inip
setiap entri (atau dalamawk
-speak: record ) diawali dan dicetak dengan tanda kutip tunggal di sekitarnya. Theawk
variabel pemisah record keluaranORS
tidak diperlukan (karena awalan melakukannya untuk Anda) sehingga diatur menjadi kosong diBEGIN
ing. Oh dan kami mungkin file kamiEND
dengan baris baru (mis. Sehingga bekerja dengan alat pemrosesan teks lebih lanjut); jika ini tidak diperlukan, bagian denganEND
dan segala sesuatu setelahnya (di dalam tanda kutip tunggal) dapat dihapus.Jika Anda memiliki ujung garis gaya Windows / DOS (
\r\n
), Anda harus mengubahnya menjadi gaya UNIX (\n
) terlebih dahulu. Untuk melakukan ini, Anda dapat meletakkantr -d '\015'
di awal pipa Anda:(Dengan asumsi Anda tidak memiliki penggunaan untuk
\r
s dalam file Anda. Asumsi yang sangat aman di sini.)Atau, jalankan
dos2unix /path/to/input.list
sekali saja untuk mengonversi file di tempat.sumber
', 'stringr23aphics
sebagai output.print p"'"'"'"$0"'"'"'"; p=", "
— Kutipan suci, Batman!p"'\''"$0"'\''";
juga akan bekerja (bukan POSIXy), atau sebagai alternatif menggunakanbash
string kutipan C ($''
) bahkan hanyaprint p"\'"$0"\'";
(mungkin perlu menggandakan backslash lainnya), tetapi ada sudah metode lain menggunakanawk
karakter lolos.Seperti jawaban @ don_crissti yang ditautkan menunjukkan, opsi tempel berbatasan dengan sangat cepat - perpipaan kernel linux lebih efisien daripada yang saya percaya jika saya tidak mencobanya sekarang. Hebatnya, jika Anda bisa bahagia dengan satu koma yang memisahkan item daftar Anda dan bukan koma + spasi, pipa tempel
lebih cepat daripada
flex
program yang masuk akal (!)Tetapi jika kinerja yang layak dapat diterima (dan jika Anda tidak menjalankan stress test, Anda tidak akan dapat mengukur perbedaan faktor-konstan, semuanya instan) dan Anda menginginkan fleksibilitas dengan pemisah dan yang masuk akal -liner-y-ness,
adalah tiketmu. Ya, sepertinya garis kebisingan, tetapi
H;1h;$!d;x
idiom adalah cara yang tepat untuk menghirup semuanya, begitu Anda dapat mengenali bahwa semuanya menjadi mudah dibaca,s/.*/'&'/
diikuti oleh slurp dan as/\n/, /g
.sunting: berbatasan dengan absurd, itu cukup mudah untuk mendapatkan flex untuk mengalahkan segalanya kosong, cukup katakan stdio Anda tidak perlu builtin multithread / signalhandler sync:
dan di bawah tekanan itu 2-3x lebih cepat dari pipa pasta, yang dengan sendirinya setidaknya 5x lebih cepat dari yang lainnya.
sumber
(paste -d\ \'\' /dev/null /dev/null - /dev/null | paste -sd, -) <infile | cut -c2-
akan melakukan koma + spasi @ kecepatan yang hampir sama meskipun seperti yang Anda catat, itu tidak benar-benar fleksibel jika Anda memerlukan beberapa string mewah sebagai pemisahflex
itu sangat keren, pria ... ini adalah pertama kalinya saya melihat seseorang mempostingflex
kode di situs ini ... upvote besar! Silakan kirim lebih banyak hal ini.Perl
Python one-liner:
Bekerja dengan cara sederhana - kami mengarahkan input.txt ke stdin menggunakan
<
operator shell , membaca setiap baris ke daftar dengan.strip()
menghapus baris baru danrepr()
membuat representasi kutipan dari setiap baris. Daftar ini kemudian bergabung menjadi satu string besar melalui.join()
fungsi, dengan,
sebagai pemisahAtau kita dapat menggunakan
+
untuk menggabungkan kutipan ke setiap baris yang dilucuti.Perl
Ide dasarnya sama seperti sebelumnya: membaca semua baris, menghapus baris baru, menyertakan tanda kutip tunggal, memasukkan semuanya ke dalam array @cvs, dan mencetak nilai-nilai array yang digabungkan dengan koma.
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
sumber
join
harus dapat mengambil iterator oleh karena itu seharusnya tidak perlu untuk mewujudkan loop stdin ke daftarSaya pikir yang berikut ini akan baik-baik saja, dengan anggapan data Anda ada dalam teks file
Mari kita gunakan array yang substitusi turun dingin:
Output dari skrip harus sebagai berikut:
Saya percaya ini yang Anda cari?
sumber
bash
dan sementara aman untuk berasumsi bahwa seseorang mungkin menggunakannya (setelah semua AFAIK itu adalah shell yang paling sering digunakan) masih belum bisa diterima begitu saja. Juga, ada bagian-bagian yang bisa membuat Anda lebih baik dalam mengutip (memasukkan tanda kutip ganda). Misalnya, walaupun nama paket tidak memiliki ruang di dalamnya, konvensi ini masih baik untuk mengutip variabel daripada tidak, Anda mungkin ingin menjalankan shellcheck.net di atasnya dan melihat catatan dan penjelasan di sana.Saya sering memiliki skenario yang sangat mirip: Saya menyalin kolom dari Excel dan ingin mengubah konten menjadi daftar yang dipisahkan koma (untuk penggunaan nanti dalam permintaan SQL seperti
... WHERE col_name IN <comma-separated-list-here>
).Ini yang saya miliki di .bashrc saya:
Saya kemudian menjalankan
lbl
("baris demi baris") pada baris cmd yang menunggu input, menempelkan konten dari clipboard, tekan<C-D>
dan fungsi mengembalikan input yang dikelilingi()
. Ini terlihat seperti ini:(Saya tidak ingat mengapa saya meletakkan dos2unix di sini, mungkin karena ini sering menyebabkan masalah dalam pengaturan perusahaan saya.)
sumber
Beberapa versi sed bertindak sedikit berbeda, tetapi pada mac saya, saya dapat menangani semuanya kecuali "uniq" di sed:
Sayangnya untuk memperbaiki bagian unik Anda harus melakukan sesuatu seperti:
--Paul
sumber
Sangat lucu bahwa menggunakan daftar teks biasa dari paket R untuk menginstalnya di R, tidak ada yang mengusulkan solusi menggunakan daftar itu langsung di R tetapi bertarung dengan bash, perl, python, awk, sed atau apa pun untuk menempatkan tanda kutip dan koma di daftar. Ini tidak perlu sama sekali dan terlebih lagi tidak menyelesaikan bagaimana input dan menggunakan daftar yang diubah dalam R.
Anda cukup memuat file teks biasa (kata,
packages.txt
) sebagai kerangka data dengan variabel tunggal, yang dapat Anda ekstrak sebagai vektor, langsung dapat digunakan olehinstall.packages
. Jadi, konversikan dalam objek R yang dapat digunakan dan instal daftar itu hanya:Atau tanpa file eksternal:
sumber