I am trying to build list of JSON objects with the files in a particular directory. I am looping thru the files
and creating the expected output object as string. I am sure there is a better way of doing this using jq
.
Can someone please help me out here?
# input
files=($( ls * ))
prefix="myawesomeprefix"
# expected output
{
"listoffiles": [
{"file":"myawesomeprefix/file1.txt"},
{"file":"myawesomeprefix/file2.txt"},
{"file":"myawesomeprefix/file3.txt"},
]
}
CodePudding user response:
You shouldn't parse the output of ls
. If installed, you could use tree
with the -J
option to produce a JSON listing, which you can transform to your needs using jq
:
tree -aJL 1 | jq '
{listoffiles: first.contents | map({file: ("myawesomeprefix/" .name)})}
'
Or more comfortably using --arg
:
tree -aJL 1 | jq --arg prefix myawesomeprefix '
{listoffiles: first.contents | map({file: "\($prefix)/\(.name)"})}
'
CodePudding user response:
This is another alternative :
jq -n --arg prefix "myawesomeprefix"\
'.listoffiles = ($ARGS.positional |
map({file:($prefix "/" .)}))'\
--args *
CodePudding user response:
You can try the nice little command line tool jc
:
ls -l | jc --ls
It converts the output of many shell commands to JSON. For reference have a look there in Github https://github.com/kellyjonbrazil/jc .
Then you can transform the result using jq
.
CodePudding user response:
If you don't have any "problematic" file names, e.g. ones that have new lines as part of their name, the following should work:
ls -1 | jq -Rn '{ listoffiles: [inputs | { file: "prefix/\(.)" }] }'
It reads each line as string, and reads them through the inputs
filter (must be combined with -n
null-input). It then builds your object.
$ cat <<LS | jq -Rn '{ listoffiles: [inputs | {file:"prefix/\(.)"}] }'
file1
file2
file with spaces
LS
{
"listoffiles": [
{
"file": "prefix/file1"
},
{
"file": "prefix/file2"
},
{
"file": "prefix/file with spaces"
}
]
}
You could use for
with a glob which should handle new lines in file names as well. But it requires you to chain 2 jq commands:
for f in *; do
printf '%s' "$f" | jq -Rs '{file:"prefix/\(.)"}';
done | jq -s '{listoffiles:.}'
To specify the prefix as variable from the outside, use --var
, e.g.
jq --var prefix "yourprefixvalue" '$prefix .'