как вывести имена файлов в кавычках в ОДНОЙ строке?

Я хочу вывести список элементов в папке следующим образом:

"filename1"  "filename2" "file name with spaces" "foldername" "folder name with spaces"

Другими словами, имена элементов должны быть в одной строке, заключены в кавычки (одинарные или двойные) и разделены пробелами.

я знаю это

find . | xargs echo

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

Этот код является частью сценария bsh. Поэтому решением может быть набор команд и использование временных файлов для хранения промежуточного вывода.

Большое спасибо за любое предложение.

Ура, Ана


person Ana    schedule 18.05.2011    source источник
comment
Если цель состоит в том, чтобы передать имена с пробелами в xargs, буквальные кавычки - неправильный способ сделать это.   -  person Charles Duffy    schedule 15.12.2015


Ответы (10)


это должно работать

find $PWD | sed 's/^/"/g' | sed 's/$/"/g' | tr '\n' ' '

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

Это должно быть более эффективным, чем предыдущее.

find $PWD | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '

Решение @ Timofey будет работать с tr в конце концов и должно быть наиболее эффективным.

find $PWD -exec echo -n '"{}" ' \; | tr '\n' ' '
person freethinker    schedule 18.05.2011
comment
Это прекрасно работает! Большое Вам спасибо. Моя последняя команда: найти. ! -тип l (-name. -o -prune) | sort -n | sed 's / ^ // g' | sed 's / $ // g' | tr '\ n' '' | xargs myCommand. Эта единственная строка была необходима как входной параметр для myCommand. - person Ana; 18.05.2011
comment
Пожалуйста, пожалуйста, нет. Во-первых, find $PWD будет плохо себя вести, если ваш $PWD содержит пробелы или буквальные символы глобуса, которые расширяются до чего угодно. Во-вторых, использование двойных кавычек вокруг имени, чтобы попытаться избежать его, является слабым механизмом, который легко обойти: допустимые имена файлов могут сами содержать символы " или ', что препятствует синтаксическому анализу всего остального потока. - person Charles Duffy; 15.12.2015
comment
@Ana, если в системе с инструментами GNU (find -print0 и sort -z), гораздо лучше использовать find ... -print0 | sort -n -z | xargs -0 myCommand - person Charles Duffy; 15.12.2015
comment
@Ana, ... даже если вы не хотите использовать NUL-разделители, вы все равно можете указать xargs использовать только разделители новой строки и обезопасить себя от имен файлов с пробелами (хотя и не с именами файлов с новой строкой, а с ответом, который вы уже приняли также уже небезопасно для имен файлов, содержащих литералы новой строки): find ... | sort -n | xargs -d $'\n' myCommand - person Charles Duffy; 15.12.2015
comment
Вам действительно следует использовать ls для вывода содержимого каталога. У него ДЕЙСТВИТЕЛЬНО есть необходимые опции. - person AnrDaemon; 26.05.2016
comment
Но как передать этот вывод с кавычками на ввод XARGS для выполнения другой команды? - person Kanagavelu Sugumar; 19.12.2018

Вы также можете просто использовать find «-printf», например:

find . -printf "\"%p\" " | xargs your_command

где:

%p = file-path

Это будет окружать каждый найденный путь к файлу кавычками и отделять каждый элемент пробелом. Это позволяет избежать использования нескольких команд.

person Benjamin A.    schedule 28.02.2013
comment
Здесь должен быть отмечен правильный ответ. Манипуляции с регулярным выражением слишком низкоуровневые. - person Sridhar Sarnobat; 25.08.2016
comment
Мне пришлось добавить новую строку, используя cygwin в Windows, чтобы вывод был таким же: -printf "\"%p\" \n" - person jcarballo; 05.09.2016
comment
-printf Недоступно в OSX. - person Nimrod; 10.11.2017
comment
@Nimrod с Homebrew: brew install findutils --with-default-names - person ; 17.05.2018
comment
... что бросается в глаза, если имя файла содержит кавычки. - person David Balažic; 08.12.2018
comment
Почему вы включили your_command? Я думал, что вопрос касается единственного варианта использования - перечисления файлов в каталоге с кавычками вокруг их имен. - person Chris Redford; 20.05.2020

Вы можете использовать GNU ls опцию --quoting-style, чтобы легко получить то, что вам нужно. На странице руководства:

--quoting-style=WORD

используйте стиль цитирования WORD для названий записей: literal, locale, shell, shell-always, shell-escape, shell-escape-always, c, escape

Например, при использовании команды ls --quoting-style=shell-escape-always ваш результат будет следующим:

'filename1' 'filename2' 'file name with spaces' 'foldername' 'folder name with spaces'

Используя --quoting-style=c, вы можете точно воспроизвести желаемый пример. Однако, если вывод будет использоваться сценарием оболочки, вы должны использовать одну из форм, которая правильно экранирует специальные символы, например shell-escape-always.

person George Hilliard    schedule 17.02.2016
comment
related: 'ls -Q'; # добавляет двойные кавычки - person splaisan; 20.09.2017
comment
Предлагаю: ls -1 --quoting-style=c - ›"file one" "file two" etc.. Спасибо. - person will; 17.10.2019

Попробуй это.

find . -exec echo -n '"{}" ' \;
person Timofey Stolbov    schedule 18.05.2011
comment
remove -n, чтобы получить результат с включенными символами новой строки. - person xastor; 28.08.2012
comment
Не работает на Solaris 11, просто печатает -n "{}" много раз! - person SharpC; 07.02.2020

for f in *; do printf "'%s' " "$f"; done; echo

Или благодаря Гордону Дэвиссону:

printf "'%s' " *; echo

Завершающий echo просто добавляет новую строку к выводу.

person glenn jackman    schedule 18.05.2011
comment
Это можно упростить еще больше: printf "'%s' " *. - person Gordon Davisson; 18.05.2011

РЕДАКТИРОВАТЬ:
Следующий ответ создает СПИСОК, разделенный новой строкой, вместо одной строки.

  1. Я предполагаю, что OP использует результат для вызова другой команды
  2. преобразовать выходной СПИСОК в одну строку очень просто (| tr '\n' ' ')

Менее упоминаемый метод - использовать параметр -d (--delimiter) для xargs:

find . | xargs -I@ -d"\n" echo \"@\" 

-I@ записывает каждый find результат как @, а затем мы выдавали его кавычками

При этом вы можете вызывать любые команды так же, как вы добавляли кавычки к аргументам.

$ find . | xargs -d"\n" testcli.js
[ "filename1",
  "filename2",
  "file name with spaces",
  "foldername",
  "folder name with spaces" ]

См. https://stackoverflow.com/a/33528111/665507

person leesei    schedule 04.01.2016

пытаться

ls | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '
person Ferroao    schedule 29.11.2018

    find . | sed "s|.*|\"&\"|"

Краткое описание:
Мы берем результат шаблона. * и заключаем его в кавычки.
Хороший источник - sed.

Подробное описание:
Шаблон: s / one / ONE /

  • s Заменить команду.
  • / Разделитель.
    В моем выражении "|" используется вместо "/", чтобы предотвратить появление "гор", как в шаблоне s / . * / \ "& \" /.
  • один шаблон поиска по шаблону регулярного выражения.
  • ONE Строка для замены.
  • . * Означает любой символ, который повторяется неограниченное количество раз.
  • \ " Означает " само по себе.
  • & Специальный символ, соответствующий найденному шаблону.
person iosuser2332    schedule 26.02.2019
comment
Пожалуйста, объясните свой ответ. - person Sagar Chauhan; 26.02.2019

Чтобы избежать взломов, пытающихся добавить кавычки вручную, вы можете воспользоваться опцией форматирования printfs %q:

❯ ll .zshrc.d
total 112K
-rwxrwxrwx 1 root root  378 Jul  1 04:39  options.zsh*
-rwxrwxrwx 1 root root   57 Jul  1 04:39  history.zsh*
-rwxrwxrwx 1 root root  301 Jul  1 05:01  zinit.zsh*
-rwxrwxrwx 1 root root  79K Jul  1 05:19  p10k.zsh*
-rwxrwxrwx 1 root root  345 Jul  1 05:24  zplugins.zsh*
-rwxrwxrwx 1 root root  490 Jul  4 23:40  aliases.zsh*
-rw-r--r-- 1 root root 9.0K Jul 27 08:14  lscolors.zsh
-rw-r--r-- 1 root root    0 Aug 30 05:56 'foo bar'
-rw-r--r-- 1 root root    0 Aug 30 05:58 '"foo"'

❯ find .zshrc.d -exec printf '%q ' {} +
.zshrc.d .zshrc.d/history.zsh .zshrc.d/aliases.zsh .zshrc.d/zplugins.zsh .zshrc.d/p10k.zsh .zshrc.d/zinit.zsh .zshrc.d/options.zsh '.zshrc.d/"foo"' '.zshrc.d/foo bar' .zshrc.d/lscolors.zsh #

vs:

find .zshrc.d -printf "\"%p\" "
".zshrc.d" ".zshrc.d/history.zsh" ".zshrc.d/aliases.zsh" ".zshrc.d/zplugins.zsh" ".zshrc.d/p10k.zsh" ".zshrc.d/zinit.zsh" ".zshrc.d/options.zsh" ".zshrc.d/"foo"" ".zshrc.d/foo bar" ".zshrc.d/lscolors.zsh" #

Обратите внимание, что файл .zshrc.d/"foo" неправильно экранирован.

❯ echo ".zshrc.d/"foo""
.zshrc.d/foo

❯ echo '.zshrc.d/"foo"'
.zshrc.d/"foo"
person mpen    schedule 30.08.2020

Спустя 10 лет никто не предложил метод Bash | while read?

find * -type d -depth 0|while read f; do echo \"$f\"; done

Это простой конвейер оболочки Bash вместо запуска другой программы, такой как sed или xarg. Если вы действительно хотите что-то сделать с каждым файлом / папкой:

find * -type d -depth 0|while read f; do du -sh "$f"; done

Кстати, find * использует другую функцию Bash, которая исключает файлы / папки .xyz и не выводит префикс ./, который делает find ..

person Michael Chen    schedule 01.05.2021