Вопрос по bash, json, sh, linux, ubuntu – преобразовать bash `ls` в массив json

19

Можно ли использовать скрипт bash для форматирования выводаls в массиве JSON? Чтобы быть действительным json, все имена каталогов и файлов должны быть заключены в двойные кавычки, разделенные запятой, а все это должно быть заключено в квадратные скобки. То есть перерабатывать:

<code>[email protected]:~/Desktop$ ls
foo.txt bar baz
</code>

в

<code>[ "foo.txt", "bar", "baz" ]
</code>

редактировать: я настоятельно предпочитаю что-то, что работает на всех моих серверах Linux; следовательно, скорее не зависит от python, но имеет чисто решение bash.

Кто-нибудь знает, как сделать это с помощью инструмента JSON манипуляции JQ?stedolan.github.io/jq/manual rektide
Вы используете не тот инструмент для этой работы. Если вы беспокоитесь о том, что python недоступен, используйте perl. Это должно быть почти на всех серверах Linux. gpojd

Ваш Ответ

11   ответов
-2

используйте язык сценариев. Пример непроверенного perl:

use JSON;
my @ls_output = `ls`; ## probably better to use a perl module to do this, like DirHandle
print encode_json( @ls_output );
1

файл JSON или XML. Почему бы не использовать эту простую команду терминала:

$ tree --dirsfirst --noreport -n -X -i -s -D -f -o my.xml

Итак, просто команда linux tree и настройте свои собственные параметры. Вот-X дает вывод XML! Для меня это нормально, и я предполагаю, что есть некоторый скрипт для преобразования XML в JSON.

ПРИМЕЧАНИЕ: я думаюэтот охватывает тот же вопрос.

-1

$ cat ls2json.bash
#!/bin/bash
echo -n '['
for FILE in $(ls | sed -e 's/"/\\"/g')
do
echo -n \"${FILE}\",
done
echo -en \\b']'

затем запустите:

$ ./ls2json.bash > json.out

но питон будет еще проще

import os
directory = '/some/dir'
ls = os.listdir(directory)
dirstring = str(ls)
print dirstring.replace("'",'"')
Хитрость в том, что не должно быть запятой после последнего элемента, прямо перед Jeroen
о, да, забыл в переводе, исправлено, проблема в том, что будет запятая. хмм.
easy fix, echo -en \\ b 'a', добавил
Вам нужно установить переменнуюset FIRST=trueи в конце цикла установите его вfalse, Выведите запятую перед FILE, когда FIRST имеет значение false.
Не могли бы вы добавить запятую, разделяющую две строки? Jeroen
17

но угловые корпуса и обработка Unicode заставят вас взобраться на стену. Лучше делегировать на язык сценариев, который поддерживает его изначально.

$ ls
あ  a  "a"  à  a b  私
$ python -c 'import os, json; print json.dumps(os.listdir("."))'
["\u00e0", "\"a\"", "\u79c1", "a b", "\u3042", "a"]
Как я уже говорил, simplejson. Это вEPEL.
Хммм. Будет ли это работать на CentOS 4? Jeroen
99,8% серверов Linux там имеют Python; правда, вам может понадобиться использовать simplejson для более старых версий Python.
Спасибо, но действительно предпочитаю что-то, что обычно работает на любом сервере Linux; поэтому я предпочитаю чистое решение Bash. Jeroen
Сервер без питона = Ад. Возможно, вы тоже скоро получите решение на Perl.
0

я бы написал скрипт, который бы запускал команду ls, отправлял вывод в файл по вашему выбору, анализируя вывод, чтобы отформатировать его в допустимый формат JSON.

Я уверен, что простой Bash-файл сработает.

Баш выход

1

echo '[' ; ls --format=commas|sed -e 's/^/\"/'|sed -e 's/,$/\",/'|sed -e 's/\([^,]\)$/\1\"\]/'|sed -e 's/, /\", \"/g'

Не справится с", \ или несколько запятых в имени файла. Кроме того, еслиls ставит новые строки между именами файлов, так же и это.

Также не будет иметь дело с символами табуляции, переводами строки или другими управляющими символами в именах файлов.
11

что ни одно имя файла не содержит символов новой строки, используйте jq:

ls | jq -R -s -c 'split("\n")'

Краткое описание флагов для jq:

-R treats the input as string instead of JSON -s joins all lines into an array -c creates a compact output

Это требует версии 1.4 или более поздней версии JQ. Попробуйте, если это не работает для вас:

ls | jq -R '[.]' | jq -s -c 'add'

ошибка: split не определен split (& quot; \ n & quot;) ^^^^^ 1 ошибка компиляции
Я пробовал обаls | jq -R -s -c 'split("\n")' а такжеls | jq -R '[.]' | jq -s -c 'add', У первой есть лишняя пустая строка & quot; добавлено в массив. Таким образом, последнее является лучшим решением.
1

что вам нужно сделать, это:

python -c 'import os, json; print json.dumps(os.listdir("/yourdirectory"))'

Это для . Каталог, вы можете добавить любой путь.

Как мы справимся с этим только для файлов?
Ваш ответ, кажется, является точной копиейstackoverflow.com/a/10234470/817632
Как бы я изменил это, чтобы следовать каталогам также?
Вы можете сделать это для разных каталогов, используя python -c & import os, json; print json.dumps (os.listdir (& quot; / mydirectory / temp & quot;)) & apos;
11

ls | awk ' BEGIN { ORS = ""; print "["; } { print "\/\@"$0"\/\@"; } END { print "]"; }' | sed "s^\"^\\\\\"^g;s^\/\@\/\@^\", \"^g;s^\/\@^\"^g"

РЕДАКТИРОВАТЬ: обновлено, чтобы решить проблему с" и пробелы. я использую/@ в качестве замены шаблона для", поскольку/ не является допустимым символом для имени файла.

Не могли бы вы рассказать, что именно делают ваши заявления на awk и sed? В частности, второе утверждение print в вашем awk и 3 sed. Вот,s^\/\@^\"^gЯ вижу, что вы избегаете/@ но я не вижу, как вы вставляете запятые между всеми записямиls.
Обратите внимание, что это решение не может правильно избегать двойных кавычек, которые могут быть в имени, например, файл с именемfoo\"bar выходит как"foo"bar" вместо"foo\"bar".
также каталоги с пробелом в имени проблематичны. Jeroen
-1, Это также страдает от классическогоParsing LS проблема.
Я решил эти две проблемы
0

myOutput = subprocess.check_output["ls"]
output = ["+str(e)+" for e in myOutput]
return output

Я не проверял, работает ли он, но вы можете найти спецификациюВот

12

он гарантированно не содержит ошибок, есть везде, а с трубами он все еще достаточно чистый:

ls | perl -e 'use JSON; @in=grep(s/\n$//, <>); print encode_json(\@in)."\n";'
& Quot; он гарантированно не содержит ошибок, он везде & quot; .... за исключением того, что вам нужно установить другой модуль .. Так что его не везде как такового. Извините, но идеальные решения включают уже доступные компоненты
Не удалось для меня, но ответ awk / sed сработал.
-1, Это страдает от классическогоParsing LS проблема. Лучше сделать это в цикле for и полностью избегать конвейера. См. Ответ Гленна Джекмана для правильного подхода.
Вам необходимо установить Perl-модуль JSON, но это работает!

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