Как объединить несколько строк имен файлов в один с пользовательским разделителем?

Я хотел бы присоединиться к результату ls -1 в одну строку и разделить его на все, что захочу.

Существуют ли какие-либо стандартные команды Linux, которые я могу использовать для этого?

Ответ 1

Аналогично самой первой опции, но опускает конечный разделитель

ls -1 | paste -sd "," -

Ответ 2

EDIT: просто " ls -m". Если вы хотите, чтобы ваш разделитель был запятой

Ah, сила и простота!

ls -1 | tr '\n' ','

Измените запятую "," на все, что вы хотите. Обратите внимание, что это включает в себя "конечную запятую"

Ответ 3

Это заменяет последнюю запятую на новую строку:

ls -1 | tr '\n' ',' | sed 's/,$/\n/'

ls -m включает символы новой строки на символе ширины экрана (например, 80-е).

В основном Bash (только ls является внешним):

saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS

Используя readarray (aka mapfile) в Bash 4:

readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS

Благодаря gniourf_gniourf для предложений.

Ответ 4

Я думаю, что это потрясающе

ls -1 | awk 'ORS=","'

ORS является "разделителем выходных записей", поэтому теперь ваши строки будут соединяться запятой.

Ответ 5

Комбинация установки IFS и использования "$*" может делать то, что вы хотите. Я использую подоболочку, поэтому я не вмешиваюсь в эту оболочку $IFS

(set -- *; IFS=,; echo "$*")

Чтобы записать вывод,

output=$(set -- *; IFS=,; echo "$*")

Ответ 6

Разбор ls вообще не рекомендуется, поэтому альтернативным вариантом является использование find, например:

find . -type f -print0 | tr '\0' ','

Или используя find и paste:

find . -type f | paste -d, -s

Для общего объединения нескольких строк (не связанных с файловой системой), проверьте: Краткий и переносимый "join" в командной строке Unix.

Ответ 7

Не изобретайте велосипед.

ls -m

Он делает именно это.

Ответ 8

только bash

mystring=$(printf "%s|" *)
echo ${mystring%|}

Ответ 9

Эта команда предназначена для вентиляторов PERL:

ls -1 | perl -l40pe0

Здесь 40 - восьмеричный код ascii для пространства.

-p будет обрабатываться по строкам и печатать

-l позаботится о замене конечного \n символом ascii, который мы предоставляем.

-e - сообщить PERL, что мы выполняем выполнение командной строки.

0 означает, что на самом деле нет команды для выполнения.

perl -e0 такой же, как perl -e ''

Ответ 10

Чтобы избежать возможной путаницы новой строки для tr, мы могли бы добавить флаг -b в ls:

ls -1b | tr '\n' ';'

Ответ 11

Похоже, ответы уже существуют.

Если вы хотите a, b, c, используйте ls -m (ответ Tulains Córdovas)

Или, если вы хотите формат a b c, используйте ls | xargs (упрощенная версия Chris Js answer)

Или, если вы хотите любой другой разделитель, например |, используйте ls | paste -sd'|' (приложение Артемов ответ)

Ответ 12

Если версия xargs поддерживает флаг -d, тогда это должно работать

ls  | xargs -d, -L 1 echo

-d - флаг разделителя

Если у вас нет -d, вы можете попробовать следующее

ls | xargs -I {} echo {}, | xargs echo

Первые xargs позволяют указать ваш разделитель, который является запятой в этом примере.

Ответ 13

sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

Пояснение:

-e - обозначает команду для запуска
 :a - это метка  /$/N - определяет область соответствия для текущей и (N) строки ext  s/\n/\\n/; - заменяет все EOL на \n
 ta; - goto label a, если матч успешный

Взято из мой блог.

Ответ 14

Седь,

sed -e ':a; N; $!ba; s/\n/,/g'
  # :a         # label called 'a'
  # N          # append next line into Pattern Space (see info sed)
  # $!ba       # if it the last line ($) do not (!) jump to (b) label :a (a) - break loop
  # s/\n/,/g   # any substitution you want

Замечания:

Это линейный по сложности, заменяющий только один раз после добавления всех строк в шаблонное пространство sed.

Ответ @AnandRajaseka и некоторые другие подобные ответы, такие как здесь, являются O (n²), потому что sed должен делать замену каждый раз, когда новая строка добавляется в Пространство Образца.

Сравнивать,

seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
  # linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
  # quadratic, hung

Ответ 15

Вы можете использовать:

ls -1 | perl -pe 's/\n$/some_delimiter/'

Ответ 16

ls выводит один вывод столбца при подключении к трубе, поэтому -1 является избыточным.

Вот еще один ответ perl, используя встроенную функцию join, которая не оставляет трейлинг-разделителя:

ls | perl -F'\n' -0777 -anE 'say join ",", @F'

Неясное -0777 заставляет perl читать все входные данные перед запуском программы.

sed альтернатива, которая не оставляет трейлинг-разделителя

ls | sed '$!s/$/,/' | tr -d '\n'

Ответ 17

Добавляя поверх ответа majkinetor, вот способ удаления конечного разделителя (поскольку я пока не могу просто комментировать его ответ):

ls -1 | awk 'ORS=","' | head -c -1

Просто удалите столько конечных байтов, сколько рассчитывает ваш разделитель.

Мне нравится этот подход, потому что я могу использовать многосимвольные разделители + другие преимущества awk:

ls -1 | awk 'ORS=", "' | head -c -2

РЕДАКТИРОВАТЬ

Как заметил Питер, отрицательный счетчик байтов не поддерживается в родной версии головы MacOS. Это, однако, может быть легко исправлено.

Сначала установите coreutils. "Основные утилиты GNU - это базовые утилиты для работы с файлами, оболочками и текстом в операционной системе GNU".

brew install coreutils

Команды, также предоставляемые MacOS, устанавливаются с префиксом "g". Например, gls.

Как только вы это сделаете, вы можете использовать, ghead с отрицательным числом байтов или лучше, сделать псевдоним:

alias head="ghead"

Ответ 18

ls имеет опцию -m, чтобы разграничить вывод с помощью ", " запятой и пробелом.

ls -m | tr -d ' ' | tr ',' ';'

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

в моем примере я заменяю разделитель , разделителем ;

заменить ; на любой один разделитель символов, который вам больше нравится, поскольку tr только учетные записи для первого символа в строках, которые вы передаете в качестве аргументов.

Ответ 19

Вы можете использовать chomp для объединения нескольких строк в одну строку:

perl -e 'while (< > ) {if (/\ $/) {chomp; } print;} 'bad0 > test

положить условие прерывания строки в if statement.It может быть особым символом или любым разделителем.

Ответ 20

Версия Quick Perl с обработкой косой черты:

ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'

Объяснить:

  • Perl -E: выполнить Perl с поддержкой функций (скажем,...)
  • скажем: печать с возвратом носителя
  • join ",", ARRAY_HERE: присоединить массив с помощью ","
  • $ _} ROWS: убрать из каждой строки оператор возврата и вернуть результат
  • <>: stdin, каждая строка является строкой, в сочетании с картой она создаст массив каждой строки