Просто альтернативное решение для bash, предполагая, что путь - это абсолютный путь (начинается с /):
#!/bin/bash
pathname="$1"
IFS='/' read -r -a p <<<"${pathname#/}"
pa="" max="${#p[@]}" i=0
while (( i<"$max" )); do
pa="$pa/${p[i++]}"
if [[ ! -e $pa ]]; then
printf 'failed at: \t"%s"\t"%s"\n' "${pa##*/}" "${pa}"
break
fi
done
$ ./script "/foo/ba r/baz/hello/world"
failed at: "hello" "/foo/ba r/baz/hello"
Для варианта использования, представленного в Вопросе, ответ @JigglyNaga, вероятно, лучше, чем этот, но для некоторых более сложных задач вы также можете перебирать элементы списка, используяkeys
:
изfile
:
for k in $(jq '.children.values | keys |.[]' file); do
...
done
или из строки:
for k in $(jq '.children.values | keys |.[]' <<< "$MYJSONSTRING"); do
...
done
Так, например. вы можете использовать:
for k in $(jq '.children.values | keys |.[]' file); do
value=$(jq -r ".children.values[$k]" file);
name=$(jq -r '.path.name' <<< "$value");
type=$(jq -r '.type' <<< "$value");
size=$(jq -r '.size' <<< "$value");
printf '%s\t%s\t%s\n' "$name" "$type" "$size";
done | column -t -s$'\t'
если у вас нет новых строк для значений, вы можете сделать это с помощью одного вызова jq
внутри цикла, что делает его намного быстрее:
for k in $(jq '.children.values | keys |.[]' file); do
IFS=$'\n' read -r -d '' name type size \
<<< "$(jq -r ".children.values[$k] |.path.name,.type,.size" file)"
printf '%s\t%s\t%s\n' "$name" "$type" "$size";
done | column -t -s$'\t'
jq -c '.children.values[]|[.path.components[0],.type,.size]'
.children.values[]
выводит каждый член массива .values
. |
направляет предыдущий результат через следующий фильтр, как в оболочковой трубе [
... ,
... ,
... ]
заставляет все термины внутри отображаться в одном массиве -c
создает "компактный" формат, т.е. один объект в строке Результат:
[".gitignore","FILE",224]
["Jenkinsfile","FILE",1396]
["README.md","FILE",237]
...
Если вы хотите вывести аккуратно выровненную -таблицу, с этой задачей лучше справятся другие инструменты, такие какcolumn
илиpaste
.
jq -c '.children.values[]|[.path.components[0],.type,.size]' | column -t -s'[],"'
-t
указывает column
угадать количество столбцов на основе ввода -s...
задает символ-разделитель (s)Результат:
.gitignore FILE 224
Jenkinsfile FILE 1396
README.md FILE 237
Это зависит от символов [
, ]
, ,
и "
, которые не появляются в ваших именах файлов, что не является безопасным предположением.
paste
также может располагать несколько входов со стороны -по стороне -. Для этого мы можем вообще удалить структуры JSON и вывести необработанные строки (шляпу -подсказку к @muru):
jq -r '.children.values[]|.path.components[0],.type,.size' | paste - - -
paste - - -
означает 3 столбца, все считанные из одного источника. На этот раз единственное предположение состоит в том, что имена файлов не содержат символов новой строки.
Решение сramda-cli
:
% curl... | ramda -o tsv '.children.values' 'map flat' 'map props ["path.name", "type", "size"]'
.gitignore FILE 224
Jenkinsfile FILE 1396
README.md FILE 237
pom.xml FILE 2548
src DIRECTORY
Сначала мы переходим к списку значений, затем сопоставляем список с помощью flat
, чтобы преобразовать каждую запись, которая является глубокой объектной структурой, в неглубокую, с ключами, разделенными точками.
Затем мы можем снова сопоставить список и выбрать нужные свойства на основе их путей, представленных в виде строк.
Наконец, -o tsv
преобразует результирующий список списков в формат tsv.
Чтобы отладить или лучше понять, что происходит, вы можете проверить, что делает каждый аргумент, удаляя их один за другим в конце команды и наблюдая за различиями в выводе на каждом шаге. Это просто операции (или функции ), применяемые к данным по одному слева направо.
jq
может преобразовывать свой вывод в различные форматы :см.https://stedolan.github.io/jq/manual/#Formatstringsandescaping
Для вкладки -отдельный вывод:
$ jq -r '.children.values[] | [.path.name,.type,.size] | @tsv' file.json
.gitignore FILE 224
Jenkinsfile FILE 1396
README.md FILE 237
pom.xml FILE 2548
src DIRECTORY
одно линейное решение на основеjtc
и xargs:
bash $ jtc -x'<values>l[+0]<size>l[-1]' -y'<name>l' -y'<type>l' -y'<size>l' your.json | xargs -n3
.gitignore FILE 224
Jenkinsfile FILE 1396
README.md FILE 237
pom.xml FILE 2548
bash $
Примечание:в вашем файле json неправильный (ключ размера присутствует не в каждой записи ), для его исключения первый аргумент -x
построен таким образом (обрабатывать только те записи, где размер присутствует ).