У меня есть следующие данные (список пакетов R, проанализированных из файла Rmarkdown), которые я хочу превратить в список, который я могу передать R для установки:
d3heatmap
data.table
ggplot2
htmltools
htmlwidgets
metricsgraphics
networkD3
plotly
reshape2
scales
stringr
Я хочу превратить список в список формы:
'd3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
В настоящее время у меня есть конвейер bash, который идет от необработанного файла к списку выше:
grep 'library(' Presentation.Rmd \
| grep -v '#' \
| cut -f2 -d\( \
| tr -d ')' \
| sort | uniq
Я хочу добавить шаг, чтобы включить новые строки в список через запятую. Я попытался добавить tr '\n' '","'
, что не удается. Я также попробовал ряд следующих ответов переполнения стека, которые также не дают результатов:
Это производит library(stringr)))phics)
в результате.
Это производит ,%
в результате.
Этот ответ (со -i
снятым флагом) производит вывод, идентичный вводу.
'
или"
.Ответы:
Вы можете добавить кавычки с помощью sed, а затем объединить строки со вставкой , например:
Если вы используете систему на основе GNU coreutils (т.е. Linux), вы можете опустить трейлинг
'-'
.Если введенные данные имеют окончания строки в стиле DOS (как предложено @phk), вы можете изменить команду следующим образом:
источник
sed 's/^\|$/"/g'|paste -sd, -
sed
одним:sed 's/.*/"&"/;:l;N;s/\n\(.*\)$/, "\1"/;tl'
paste
один;)awk
: Альтернатива с меньшим количеством экранирования и, следовательно, более читабельным: Выход: Объяснение:Сам
Заметкаawk
скрипт без всякого побега естьBEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. После печати первой записи переменнаяp
устанавливается (до этого она похожа на пустую строку). С этой переменнойp
каждая запись (или вawk
-speak: record ) имеет префикс и дополнительно печатается в одинарных кавычках.awk
Переменная разделитель выходных записейORS
не требуется (так как префикс делает это для вас) , поэтому он установлен быть пустым вBEGIN
Инж. Да, и мы можем отправить наш файлEND
с новой строкой (например, чтобы он работал с другими инструментами обработки текста); если в этом нет необходимости, часть сEND
и все после нее (внутри одинарных кавычек) можно удалить.Если у вас есть окончания строк в стиле Windows / DOS (
\r\n
), вы должны\n
сначала преобразовать их в стиль UNIX ( ). Для этого вы можете поместитьtr -d '\015'
в начало вашего конвейера:(Предполагая, что вы не используете
\r
s в вашем файле. Очень безопасное предположение здесь.)Или просто запустите
dos2unix /path/to/input.list
один раз, чтобы преобразовать файл на месте.источник
', 'stringr23aphics
в качестве вывода.print p"'"'"'"$0"'"'"'"; p=", "
- святые цитаты, Бэтмен!p"'\''"$0"'\''";
также работала бы (хотя это не POSIXy), или, альтернативно, использовала быbash
строки цитирования C ($''
) даже простоprint p"\'"$0"\'";
( хотя, возможно, потребовалось бы удвоить другие обратные слэши), но есть уже другой метод, использующийawk
символ `ы '.Как показывает связанный ответ @ don_crissti , опция вставки граничит с невероятно быстрой скоростью - конвейер ядра Linux более эффективен, чем я мог бы поверить, если бы не попробовал его сейчас. Примечательно, что если вас устраивает одна запятая, разделяющая элементы списка, а не запятая + пробел, конвейер вставки
быстрее, чем даже разумная
flex
программа (!)Но если приемлема только приличная производительность (и если вы не проводите стресс-тестирование, вы не сможете измерить различия с постоянными коэффициентами, они все мгновенные), и вам нужны как гибкость с вашими разделителями, так и разумная. -liner-у-ность,
это твой билет Да, это похоже на линейный шум, но
H;1h;$!d;x
идиома - это правильный способ заморозить все, как только вы поймете, что все становится действительно легко читаемым, заs/.*/'&'/
ним следуют глухой и as/\n/, /g
.редактирование: граничит с абсурдом, довольно легко добиться гибкости, чтобы превзойти все остальное, просто скажите stdio, что вам не нужна встроенная синхронизация многопоточной обработки / обработки сигналов:
и в состоянии стресса это в 2-3 раза быстрее, чем конвейеры пасты, которые сами по крайней мере в 5 раз быстрее, чем все остальное.
источник
(paste -d\ \'\' /dev/null /dev/null - /dev/null | paste -sd, -) <infile | cut -c2-
будет делать запятую + пробел @ почти с той же скоростью, хотя, как вы заметили, она не очень гибкая, если вам нужна какая-тоflex
чертовски крутой человек ... это первый раз, когда я вижу, как кто-то публикуетflex
код на этом сайте ... большое upvote! Пожалуйста, опубликуйте больше этого материала.Perl
Python однострочный:
Работает просто - мы перенаправляем input.txt в stdin, используя
<
оператор оболочки , читаем каждую строку в список,.strip()
удаляя символы новой строки иrepr()
создавая представление каждой строки в кавычках. Затем список объединяется в одну большую строку через.join()
функцию с,
разделителем.В качестве альтернативы мы могли бы использовать
+
конкатенацию кавычек для каждой зачистки.Perl
По сути, та же идея, что и раньше: читать все строки, зачеркивать завершающий символ новой строки, заключать в одинарные кавычки, помещать все в массив @cvs и выводить значения массива, объединенные запятыми.
'D3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'весы', 'stringr'
источник
join
должны иметь возможность взять итератор, поэтому не должно быть необходимости материализовать цикл stdin в списокЯ думаю, что следующее должно быть хорошо, если вы данные в тексте файла
Давайте использовать массивы, которые имеют подстановку внизу:
Вывод скрипта должен быть следующим:
Я полагаю, это было то, что вы искали?
источник
bash
и хотя можно с уверенностью предположить, что кто-то может его использовать (в конце концов, AFAIK - это наиболее используемая оболочка), его все равно не следует воспринимать как должное. Кроме того, есть части, которые вы могли бы лучше использовать при цитировании (вставляя двойные кавычки). Например, несмотря на то, что в именах пакетов вряд ли есть пробелы, по-прежнему целесообразно заключать в кавычки переменные, а не нет, вы можете захотеть запустить shellcheck.net и посмотреть там примечания и пояснения.У меня часто бывает очень похожий сценарий: я копирую столбец из Excel и хочу преобразовать содержимое в список через запятую (для последующего использования в запросе SQL, например
... WHERE col_name IN <comma-separated-list-here>
).Это то, что у меня есть в моем .bashrc:
Затем я запускаю
lbl
(«строка за строкой») в строке cmd, которая ожидает ввода, вставляю содержимое из буфера обмена, нажимаю,<C-D>
и функция возвращает ввод, окруженный()
. Это выглядит так:(Я не помню, почему я поместил dos2unix здесь, предположительно, потому что это часто вызывает проблемы в настройке моей компании.)
источник
Некоторые версии sed ведут себя немного иначе, но на моем mac я могу обрабатывать все, кроме «uniq» в sed:
К сожалению, чтобы исправить уникальную часть, вы должны сделать что-то вроде:
--Павел
источник
Забавно, что если использовать простой текстовый список пакетов R для их установки в R, никто не предлагал решения, использующего этот список непосредственно в R, а боролся с bash, perl, python, awk, sed или чем-то другим, чтобы поставить кавычки и запятые в список. Это вовсе не обязательно и, более того, не решает, как вводить и использовать преобразованный список в R.
Вы можете просто загрузить простой текстовый файл (скажем,
packages.txt
) в виде фрейма данных с одной переменной, которую вы можете извлечь как вектор, непосредственно используемый дляinstall.packages
. Итак, преобразуйте его в полезный объект R и установите этот список просто:Или без внешнего файла:
источник