convert bash `ls` output to json array

2020-02-08 06:00发布

问题:

Is it possible to use a bash script to format the output of the ls to a json array? To be valid json, all names of the dirs and files need to be wrapped in double quotes, seperated by a comma, and the entire thing needs to be wrapped in square brackets. I.e. convert:

jeroen@jeroen-ubuntu:~/Desktop$ ls
foo.txt bar baz

to

[ "foo.txt", "bar", "baz" ]

edit: I strongly prefer something that works across all my Linux servers; hence rather not depend on python, but have a pure bash solution.

回答1:

Use perl as the encoder; it's guaranteed to be non-buggy, is everywhere, and with pipes, it's still reasonably clean:

ls | perl -e 'use JSON; @in=grep(s/\n$//, <>); print encode_json(\@in)."\n";'


回答2:

Yes, but the corner cases and Unicode handling will drive you up the wall. Better to delegate to a scripting language that supports it natively.

$ ls
あ  a  "a"  à  a b  私
$ python -c 'import os, json; print json.dumps(os.listdir("."))'
["\u00e0", "\"a\"", "\u79c1", "a b", "\u3042", "a"]


回答3:

If you know that no filename contains newlines, use jq:

ls | jq -R -s -c 'split("\n")[:-1]'

Short explanation of the flags to jq:

  • -R treats the input as string instead of JSON
  • -s joins all lines into an array
  • -c creates a compact output
  • [:-1] removes the last empty string in the output array

This requires version 1.4 or later of jq. Try this if it doesn't work for you:

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



回答4:

Hello you can do that with sed and awk:

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

EDIT: updated to solve the problem with " and spaces. I use /@ as replacement pattern for ", since / is not a valid character for filename.



回答5:

Here's a bash line

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

Won't properly deal with ", \ or some commas in the name of the file. Also, if ls puts newlines between filenames, so will this.



回答6:

Most of the Linux machine already has python. all you have to do is:

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

This is for . directory , you can add any path.



回答7:

I was also searching for a way to output a Linux folder / file tree to some JSON or XML file. Why not use this simple terminal command:

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

so, just the linux tree command, and config your own parameters. Here -X gives XML output! For me, that's OK, and i guess there's some script to convert XML to JSON ..

NOTE: I think this covers the same question.



回答8:

Personnaly, I would code script that would run the command ls, send the output to a file of you choice while parsing the output to make format it to a valid JSON format.

I'm sure that a simple Bash file will do the work.

Bash ouput



回答9:

Can't you use a python script like this?

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

I didn't check if it works, but you can find the specification here



回答10:

Should be pretty easy.

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

then run:

$ ./ls2json.bash > json.out

but python would be even easier

import os
directory = '/some/dir'
ls = os.listdir(directory)
dirstring = str(ls)
print dirstring.replace("'",'"')


回答11:

Don't use bash, use a scripting language. Untested perl example:

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