Ответы:
Ниже приведены дюжина примеров того, как вы можете взять файл, такой как этот:
$ cat k.txt
1
2
3
и преобразовать его в этот формат:
1,2,3
Вы можете использовать эту команду для создания вышеуказанного файла, если вы хотите подыграть:
$ cat <<EOF > k.txt
1
2
3
EOF
Приведенные ниже примеры разбиты на 2 группы. Те, которые "работают" и те, которые "почти" работают. Я оставляю это, потому что часто так же важно видеть, почему что-то не работает, так же как и видеть, почему что-то работает.
Представлено большинство языков сценариев, с которыми я знаком. Некоторые представлены несколько раз, поскольку, как и в известной аббревиатуре, на которую обычно ссылается Perl, TIMTOWTDI .
Примечание: Вы можете поменять запятую ( ,
) в примерах ниже , и заменить его любые символы , которые вы хотите, то есть |
.
Эти фрагменты кода будут давать желаемый результат.
Команда paste
:
$ paste -s -d ',' k.txt
1,2,3
Команда sed
:
$ sed ':a;N;$!ba;s/\n/,/g' k.txt
1,2,3
$ sed ':a;{N;s/\n/,/};ba' k.txt
1,2,3
Команда perl
:
$ perl -00 -p -e 's/\n(?!$)/,/g' k.txt
1,2,3
$ perl -00 -p -e 'chomp;tr/\n/,/' k.txt
1,2,3
Команда awk
:
$ awk '{printf"%s%s",c,$0;c=","}' k.txt
1,2,3
$ awk '{printf "%s,",$0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk -vORS=, 1 k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk 'BEGIN {RS="dn"}{gsub("\n",",");print $0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
Команда python
:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,3
$ python -c "import sys; print sys.stdin.read().replace('\n', ',').rstrip(',')" <k.txt
1,2,3
mapfile
Встроенный Bash :
$ mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
1,2,3
Команда ruby
:
$ ruby -00 -pe 'gsub /\n/,",";chop' < k.txt
1,2,3
$ ruby -00 -pe '$_.chomp!"\n";$_.tr!"\n",","' k.txt
1,2,3
Команда php
:
$ php -r 'echo strtr(chop(file_get_contents($argv[1])),"\n",",");' k.txt
1,2,3
Предостережения
Большинство приведенных выше примеров будут работать просто отлично. У некоторых есть скрытые проблемы, такие как пример PHP выше. Функция chop()
на самом деле является псевдонимом rtrim()
, поэтому завершающие пробелы последней строки также будут удалены.
То же самое касается первого примера Ruby и первого примера Python. Проблема заключается в том, как они все используют тип операции, которая по сути "слепо" отсекает конечного персонажа. Это хорошо для примера, который предоставил OP, но следует соблюдать осторожность при использовании этих типов однострочников, чтобы убедиться, что они соответствуют данным, которые они обрабатывают.
пример
Скажем, наш образец файла k.txt
выглядел так:
$ echo -en "1\n2\n3" > k.txt
Выглядит похоже, но есть одно небольшое отличие. У него нет завершающего символа новой строки ( \n
), как в оригинальном файле. Теперь, когда мы запускаем первый пример Python, мы получаем это:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,
Это примеры «всегда подружка невесты, а не невеста» . Большинство из них, вероятно, могут быть адаптированы, но когда вы работаете с потенциальным решением проблемы, когда она чувствует себя «вынужденной», это, вероятно, неправильный инструмент для работы!
Команда perl
:
$ perl -p -e 's/\n/,/' k.txt
1,2,3,
Команда tr
:
$ tr '\n' ',' < k.txt
1,2,3,
В cat
+ echo
команды:
$ echo $(cat k.txt)
1 2 3
Команда ruby
:
$ ruby -pe '$_["\n"]=","' k.txt
1,2,3,
Встроенные Bash while
+ read
:
$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,
awk
я предпочитаю более короткую альтернативу:awk -vORS=, 1 k.txt
bash
:mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
perl
и у первого awk
они тоже есть.
paste
один наверху. Это именно то, что paste -s
здесь. Это стандартная команда, и она будет наиболее эффективной. Все остальные излишни и / или не переносимы или имеют ограничения.
mapfile
относительно новый, добавлен в bash
4.0.
@slm уже дал хороший ответ, но в качестве вашего вопроса "отформатируйте вывод xargs"
xargs -I{} echo -n "{}|" < test.txt
-I
опция "заменить строки"{}
является заполнителем для выходного текста.Если вы хотите избавиться от трейлинга, |
вы можете использовать его sed
для очистки:
$ xargs -I{} echo -n "{}|" < k.txt | sed -e 's/|$//'
1|2|3
tr
, sed
и другие также ..
Это старая ветка, я знаю. ОП спросил с простым кодом, как это. Чтобы приблизить его к оригиналу, у меня есть простое решение.
cat k.txt | xargs
1 2 3
использовать сед
cat k.txt | xargs | sed 's/ /,/g'
1,2,3
или
cat k.txt | xargs | sed 's/ /|/g'
1|2|3
Sed может выглядеть немного странно, но разбито, это имеет большой смысл.
для замены. g 'для global: без этого он будет выполнять только первую замену в каждой новой строке. Поскольку вы используете 'xargs', он отображает их одной строкой. Таким образом, вы получите «1,2 3».
Разделитель используется для разделения. Я использовал символ /. Один интересный трюк: вы можете заменить разделитель большинством других символов, если мы оставим его в том же формате между кавычками. Так что это будет работать также ....
cat k.txt | xargs | sed 's# #,#g'
или
cat k.txt | xargs | sed 'sT T,Tg'
Очевидно, что использование определенных символов в качестве разделителя может привести к путанице, поэтому будьте умны.
xargs <k.txt | tr \ \|
Вам не нужно cat
- просто передайте входные данные файла и - если не будет дано никакой другой команды - xargs
передадите его формат по умолчанию - который имеет тип с (без интерпретации c-escape/bin/echo
с обратной косой чертой) .
xargs
удалит пустые места заголовка / хвоста из входного файла и сожмет другие последовательности пробелов вниз до одного пробела. Это означает , что при прохождении файла из tr
к xargs
как:
tr \\n \| <k.txt | xargs
... печать ...
1|2|3|
... идти другим путем и работать только с аргументами, которые xargs
разделяет пробел ....
1|2|3\n
... потому что xargs
печатает последний завершающий символ новой строки (как требуется для текстового файла) , но он не tr
обрабатывается таким образом.
Обратите внимание, что это (или любое другое решение, предлагаемое здесь) не учитывает xargs
цитирование при вводе. xargs
будет выдавать буквально одинарные / двойные / обратные слэш-символы, не являющиеся символом новой строки, при вводе, которые сами могут быть процитированы как
xargs <<\IN
1 2' 3'\' \'4
IN
1 2 3' '4
xargs cat -n
, но проще , если вы просто обрезать символы новой строки, это может быть достигнуто сecho $(cat)
,grep
илиawk
(ползание так , как это сделать).xargs
не подходят для вашей текущей цели.