convert bash `ls` output to json array
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";'
Convert bash `ls` output to json array and print working directory to every element in the JSON array
One way:
(cd .. && find Readme -print0) | jq -sR 'split("\u0000")[1:]'
How to convert string list to JSON string array in Bash?
If your jq has inputs
then the simplest would probably be to use it:
jq -ncR '[inputs]' <<< "$groups"
["group1","group2","group3"]
Otherwise, here are three alternatives:
jq -c -n --arg groups "$groups" '$groups | split("\n")'
echo -n "$groups" | jq -cRs 'split("\n")'
echo "$groups" | jq -R -s -c 'split("\n") | map(select(length>0))'
In any case, the array can easily be incorporated into a JSON object, e.g. by extending the filter with | {groups: .}
If you really want to produce invalid JSON, consider:
printf "%s" "$groups" | jq -Rrsc 'split("\n") | "{ \(.) }"'
Output:
{ ["group_1","group_2","group_3"] }
Note on select(length>0)
Consider:
jq -Rsc 'split("\n")' <<< $'a\nb'
["a","b",""]
The reason for including select(length>0)
is to avoid the trailing "".
If $groups contains consecutive newlines, and if it is important to retain the empty strings, then you might want to use [:-1]
, e.g.
jq -cRs 'split("\n")[:-1]' <<< "$groups"
["group1","group2","group3"]
If your jq does not support [:-1]
, make the 0 explicit: [0:-1]
Convert arbitrary output to json by column in the terminal?
I found a great list of tools to work with command line output, and one of the tools listed is sqawk which will convert any arbitrary data to json, and let you filter it using sql like queries!
Convert ps
output to JSON
ps | sqawk -output json,indent=1 'select PID,TTY,TIME,CMD from a' trim=left header=1
Output
[{
"PID" : "3947",
"TTY" : "pts/2",
"TIME" : "00:00:07",
"CMD" : "zsh"
},{
"PID" : "15951",
"TTY" : "pts/2",
"TIME" : "00:00:00",
"CMD"
}]
converting lines to json in bash
I was also trying to convert a bunch of lines into a JSON array, and was at a standstill until I realized that -s
was the only way I could handle more than one line at a time in the jq
expression, even if that meant I'd have to parse the newlines manually.
jq -R -s -c 'split("\n")' < just_lines.txt
-R
to read raw input-s
to read all input as a single string-c
to not pretty print the output
Easy peasy.
Edit: I'm on jq
≥ 1.4, which is apparently when the split
built-in was introduced.
Append new element to JSON object in specific format using bash and jq
This requires jq
1.6 in order to use the --args
option.
$ jq --arg wd "$(basename "$PWD")" '.docs+={($wd): $ARGS.positional | map("\($wd)/\(.)")}' ../RandomFile.json --args *
{
"docs": {
"Doc": [
"doc1"
],
"Readme": [
"Readme/Readme.md",
"Readme/Readyou.md"
]
}
}
- The shell is used to pass the base name of the current working directory as the variable
$wd
. - The shell is also used to pass the names of all the files in the current working directory as separate arguments.
- The file to edit is assumed to be
../RandomFile.json
; if you only know that there is a JSON file in the parent, you can use../*.json
instead. - Use
+=
to update the.docs
object of the original with a new key (the working directory) and list of file names.map
prefixes each element of$ARGS.positional
with$wd
.
return specific items in json object using bash
You need to do two things: one, use the -s
option so that each separate object becomes an element of a single array. Two, you are trying to index the Name
, instead of accessing the Name
attribute of an array element.
$ jq -sr '.[].Name' tmp.json
testuser1
testuser2
If you wanted to refer to a specific element of the stream, you could:
$ jq -sr '.[1].Name' tmp.json
testuser2
With that (and assuming none of your names will contain newlines), a proper loop would look like
while IFS= read -r name; do
...
done < <(jq -sr '.[].Name' tmp.json)
Convert a nested JSON of objects into array into a bash array using jq
to_entries
has nothing whatsoever to do with exposing JQ results to bash. Rather, it takes each entry in a JSON object and emits a {"key": key, "value": value}
pair.
That can be useful, if you want to identify and extract arbitrary keys. For example:
#!/usr/bin/env bash
jq_script='
.profile.download.entries[]
| select(.store == "A")
| to_entries[]
| select(.key != "store")
| select(.key != "type")
| [.key, .value]
| @tsv
'
declare -A array=( )
while IFS=$'\t' read -r key value; do
array[$key]=$value
done < <(jq -r "$jq_script")
# print array output
declare -p array
...will, when given your input on stdin, emit (albeit on a single line, without the whitespace changes):
declare -A array=([ENTRY_A]="testserver1_place_com"
[ENTRY_B]="testserver2_anotherplace_com" )
...which I assume, for lack of any better description in the question, is what you actually want.
Related Topics
Using Rsync Include and Exclude Options to Include Directory and File by Pattern
Read Line by Line in Bash Script
How Much Memory Is Consumed by the Linux Kernel Per Tcp/Ip Network Connection
Tcp_Tw_Reuse VS Tcp_Tw_Recycle:Which to Use (Or Both)
How to Create Threads Without System Calls in Linux X86 Gas Assembly
One Core Exclusively for My Process
Export Not Working in My Shell Script
Sed Command with -I Option (In-Place Editing) Works Fine on Ubuntu But Not MAC
Centos Through a Vm - No Urls in Mirrorlist
Linux Cross-Compilation for Arm Architecture
Adding Timestamp to a Filename with Mv in Bash
Use Grep to Find Content in Files and Move Them If They Match
Getting List of Network Devices Inside the Linux Kernel