awk-печать значения столбца без новой строки и добавление запятой

Они, были в fs/super.c в Linux 2.4:

В моей машине (Linux 2.6.24) они находятся в fs/namespace.c:

В Linux 2.6.39 (который является последней конюшней) я не мог найти sys_mount функционируйте, но я нашел compat_sys_mount функция в /fs/compat.c.

Благодаря Gilles для указания на устаревшую информацию.

4
04.08.2012, 02:02
7 ответов
awk 'BEGIN{ORS=","}1' input.txt

урожаи это:

EN1,EN2,EN3,EN4,EN5,

так печатает с запятой (таким образом, я не уверен, что понимаю Ваш комментарий в Вашем сообщении об этом не происходящем), хотя я подозреваю, что запаздывающая запятая является проблемой.

Протестированный с GNU Awk 3.1.7

6
27.01.2020, 20:45
  • 1
    Это печатает без запятой, например, EN1EN2EN3EN4EN5 –  jack 04.08.2012, 00:47
  • 2
    , какую версию awk Вы используете? Это нечетно, так как я вставил это в от консоли. –  Levon 04.08.2012, 00:49
  • 3
    Вопрос использовал OFS, этот ответ использование ORS .. это объясняет различие в поведении... printf не производит ORS –  Peter.O 04.08.2012, 02:58

Можно использовать tr в такой ситуации.

tr '\n' ',' <input.txt

Это заменяет заключительную новую строку запятой также. Для предотвращения этого, на Linux, если Вы знаете, что входной файл действительно заканчивается новой строкой:

<input.txt head -c -1 | tr '\n' ,

Добавить ; echo если Вы хотите, чтобы вывод был завершен новой строкой.

С другой стороны, можно заставить оболочку удалять запаздывающую запятую, если существует тот.

columns=$(<input.txt tr '\n' ',')
echo "${columns%,}"
4
27.01.2020, 20:45
  • 1
    Достаточно странно это дает мне "дополнительный операнд" сообщение об ошибке, но tr '\n' ',' < input.txt хорошо работает, но также и с запаздывающей запятой. –  Levon 04.08.2012, 00:59
  • 2
    @Levon Видит мой –  Gilles 'SO- stop being evil' 04.08.2012, 02:02
  • 3
    @Gilles.. работает хороший (не приезжайте часто через команду, которая запускается с <) –  Levon 07.08.2012, 18:09

Существует также xargs и sed:

$ xargs <input.txt | sed -e 's/ /,/g'
EN1,EN2,EN3,EN4,EN5

Преимущество здесь состоит в том, что нет никакой запаздывающей запятой для избавлений от.

xargs объединить входные строки, sed заменять все пробелы запятыми. Я использую это обычно для построения регулярных выражений (пробелы замены с |) и быстрые суммы для передачи по каналу в bc (замените пробелы +).

(К ВАШЕМУ СВЕДЕНИЮ xargs значения по умолчанию к echo как команда, если ни один не обеспечивается),

Примечание: Это только работает, если входной файл как описан (одно поле на строку, никакие пробелы). Если существует больше полей и/или пробелов во входе, можно использовать awk или sed, чтобы предварительно обработать вход. Например, с входом как это:

EN1 foo bar
EN2 bar foo
EN3 baz quux
EN4 abc def
EN5 hij klm

Здесь awk используется для извлечения только первого поля:

$ awk '{print $1}' input.txt | xargs | sed -e 's/ /,/g'
EN1,EN2,EN3,EN4,EN5

В этом втором (sed) примере пробелы в исходном входе заменяются некоторой другой строкой (выбранный в качестве маловероятных быть в исходном входе), затем питаемый в xargs. sed затем заменяет пробелы, добавленные xargs, и затем восстанавливает строки от входа:

$ sed -e 's/ /--space--/g' input.txt | xargs | sed -e 's/ /,/g' -e 's/--space--/ /g'
EN1 foo bar,EN2 bar foo,EN3 baz quux,EN4 abc def,EN5 hij klm

Теперь для некоторого бесплатного комментария страницы публицистики:

Одна из самых полезных частей знания об инструментах обработки текста Unix - то, что Вы можете и если должен думать о данных, как являющихся почти бесконечно покорным - можно преобразовать его в любую форму, которую Вы должны или предоставить входу другому процессу или произвести вывод, который Вы хотите или оба.

Это - часть причины, почему люди Unix склонны ненавидеть собственные форматы данных - это не просто философское неодобрение или желание избежать зависимости от поставщика, это - также очень прагматическое то, что они мешают нам управлять и использовать наши данные способами, которые не были предсказаны разработчиками программного обеспечения.

3
27.01.2020, 20:45
  • 1
    Это не будет проблема в большинстве случаев, и для того, конечно, очень полезно, что Вы упомянули, но это действительно производит запаздывание \n, и если xargs потребности вызвать echo многократно из-за командной строки args пределы, sed представит более побочный \ns; один для каждого дополнительного вызова... (+1 BTW) –  Peter.O 04.08.2012, 22:58
  • 2
    PS.. Я просто заметил это xargs echo -n избегает \n выйдите..., но sed может поразить предел памяти (он сделал в моих довольно крупномасштабных тестах), таким образом, должно быть хорошо, если Вы не имеете дело с гигабайтом + долгие командные строки ;) –  Peter.O 04.08.2012, 23:20
  • 3
    да, ну, в общем, xargs разделит их задолго до того, как командные строки добираются до гигабайта :). Я иногда сталкивался с проблемами при генерации огромных командных строк от find /really/stupidly/long/path/.../ | xargs но это - больше проблема с командой, в которую я подаю ее, чем с xargs (например, 'du-sh' может генерировать несколько общих строк, которые затем должны быть добавлены), и разрешимо с подходящим сценарием обертки или последующей обработкой. –  cas 05.08.2012, 13:06
perl -pe '(eof)?s/\s+$//:s/\s+$/,/' input.txt  

вывод: никакое запаздывание \n

EN1,EN2,EN3,EN4,EN5
1
27.01.2020, 20:45

Я знаю, старая тема, но я не мог сопротивляться - вот еще один короткий и простой способ сделать это:

$ paste -sd, input.txt
EN1,EN2,EN3,EN4,EN5
$

работает на Linux и Solaris, может быть, даже на других платформах.

3
27.01.2020, 20:45

Решение, которое не печатает запятую в конце строки:

{printf("%s", NR == 1 ? $0 : ","$0);} END {printf("\n");} file

Пояснение

Когда видна первая строка (NR == 1), печатается только она; в противном случае запятая и строка передаются в качестве аргументов printf.

Это решение использует троичный оператор AWK ?:, то есть:

NR == 1 ? $0 : ","$0

Если переменная NR равна 1, то в качестве аргумента в printf отправляется первая строка; в противном случае отправляется запятая, скомпонованная с текущей строкой.

2
27.01.2020, 20:45
sed -z 's/\n/,/g' input.txt

Опция -z(только в sed версии 4.2 или более поздней )ожидает нулевой -байт в качестве символа конца записи вместо символа новой строки, обрабатывая весь этот входной файл как одну строку. Найдите\n(символ новой строки )и замените запятой. gделает поиск -заменой глобального.

Он также преобразует последний символ новой строки в запятую, но конечную запятую легко преобразовать обратно:

sed -z 's/\n/,/g' input.txt | sed 's/,$/\n/'

Символ $отмечает конец строки, поэтому последняя запятая заменяется символом новой строки.

Обратите внимание, что если ваш входной файл содержит какие-либо нулевые -байты (, часто используемые в двоичных файлах для завершения строк ), тогда они будут рассматриваться как маркеры конца записи. Приведенный выше пример не должен быть затронут, но в некоторых ситуациях он может дать неожиданные результаты.

0
27.01.2020, 20:45

Теги

Похожие вопросы