How format mac address inside json array - sed

Need help in getting below the mac address inside the json file to re-reformatted using sed
cat 251.json
cat /tmp/251.json
[
"08:f1:ea:6d:03:3c",
"08:f1:ea:6d:03:3d",
"08:f1:ea:6d:03:3e",
"08:f1:ea:6d:03:3f",
"b8:83:03:81:4b:20",
"b8:83:03:81:4b:21",
"b8:83:03:84:d5:1c",
"b8:83:03:84:d5:1d"
]
The expected format is
[
"08f1.ea6d.033c",
"08f1.ea6d.033d",
"08f1.ea6d.033e",
"08f1.ea6d.033f",
"b883.0381.4b20",
"b883.0381.4b21",
"b883.0384.d51c",
"b883.0384.d51d"
]

This should work:
sed -E 's/:(.{2}):(.{2}):(.{2}):(.{2}):/\1.\2\3.\4/g' /tmp/251.json
In this way, you get the output to stdout. If you want to modify the file, add the -i option. You can check the result here.

Related

Cloud Foundry: How do I get the contents of the VCAP_SERVICES environment variable? (and only this variable!)

When I deploy an app to Cloud Foundry and attach it to instances of Cloud Foundry services,
and I use the Cloud Foundry CLI to get the environment variables: cf env my-app,
then I get an output like:
Getting env variables for app my-app in org my-org / space my-space as user#company.com...
System-Provided:
VCAP_SERVICES: {
"service1": [
// ...
],
"service2": [
// ...
]
}
VCAP_APPLICATION: {
// ...
}
User-Provided:
VARIABLE1: value
VARIABLE2: value
Running Environment Variable Groups:
CREDHUB_API: https://credhub.company.com
No staging env variables have been set
How do I filter this output to get only the contents of the environment variable VCAP_SERVICES, so that when I test/debug my app locally, it behaves as if it was attached to the instances of the Cloud Foundry services?
My goal is to write a file named default-env.json containing only:
{
VCAP_SERVICES: {
"service1": [
// ...
],
"service2": [
// ...
]
}
}
Ideally, the command to produce this output should be a zsh one-liner.
cf env my-app | sed -n '/VCAP_SERVICES/,/VCAP_APPLICATION/p' | sed '$d' | sed '1s;^;{\n;' | sed '$s/$/}/' > default-env.json
Explanation
sed -n '/VCAP_SERVICES/,/VCAP_APPLICATION/p'
keeps only the section between the regular expressions VCAP_SERVICES and VCAP_APPLICATION.
sed '$d' deletes the last line (the line containing VCAP_APPLICATION).
sed '1s;^;{\n;' prepends {\n to the first line.
sed '$s/$/}/' appends } to the end of the file.
Credits
Handy one-liners for SED
BASH Prepend A Text / Lines To a File
SED: insert text after the last line?
Another option would be:
cf curl "/v2/apps/$(cf app --guid my-super-cool-app)/env" | jq -r '.system_env_json.VCAP_SERVICES'
Explanation:
$(cf app --guid <your-app-name) will run in a subshell and get the app guid for your app. You could alternatively just replace that bit with the guid for your app, if you know it already (it'll make the command faster).
cf curl "/v2/apps/<guid>/env" will return all of the env variables for your app.
jq -r '.system_env_json.VCAP_SERVICES' picks out the bit you want.
You could optionally redirect output to a file.
Other interesting bits from that API:
.application_env_json.VCAP_APPLICATION would give you VCAP_APPLICATION.
'.environment_json' would give you any env variables you've set

Using sed, delete from specific line until first match(not included)

I have some data looks like
1:Alice 2313
2:Desctop 456
3:Cook 111
4:.filename 50
...
...
100:Good 3
Dir num:10
File num:90
...
...
I want to delete all lines from specific line(ex. line 3) until the line "Dir num:" show up.
The idea output should be(according above example):
1:Alice 2313
2:Desctop 456
Dir num:10
File num:90
...
...
I have google several solutions likesed -i '/somestring/,$!d' file.
But these solutions are not suitable because of the specific line where deletion satarting.
How can I do this in 1 command without any tmp file?
Forgive my poor English, I'm not native English speaker.
You need to specify the address range from the specified line number (3) to the line matching the pattern (/Dir num/). However, it's not quite as simple as
sed '3,/Dir num/ d' file
because that will delete the "Dir num" line. Try this instead:
sed '3,/Dir num/ {/Dir num/! d}' file
That will, for the lines in the range, check that the line does not match the pattern: is the pattern is not matched, delete it.
Use the range: /pattern1/,/pattern2/ option of sed
$ sed -e '/2:Desctop 456/,/Dir num:10/{//!d}' inputFile
1:Alice 2313
2:Desctop 456
Dir num:10
File num:90
...
...

How can I use grep to remove extraneous entries from Unity's logcat output?

You get logcat output from Unity by using the following command;
adb logcat -s Unity
Here is a typical log message that each output call would generate;
02-16 09:17:09.245 18683 27815 I Unity : I [HTTPRequest]: Sending request: POST /ws/1/entry/1/global HTTP/1.1
02-16 09:17:09.245 18683 27815 I Unity :
02-16 09:17:09.245 18683 27815 I Unity : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
How can I use grep to return the first line above but not the 2nd or 3rd lines? I know that I can use -v to invert the matching, and therefore can remove the 'DebugBindings' line using the following;
adb logcat -s Unity | grep -v DebugBindings
But how can I also exclude the empty lines?
grep -Ev '^.*?Unity\s*:$' file
-E grep with extended-regexp
.*?Unity allow all characters until first occurrence of the word "Unity"
\s*:$ allow any number of spaces followed by : and end of line

Search xml for a value using sed

I have a below xml file
<documents>
<document><title>some title1</title><abstract>Some abstract1</abstract></document>
<document><title>some title2</title><abstract>Some abstract2</abstract></document>
<document><title>some title3</title><abstract>Some abstract3</abstract></document>
<document><title>some title4</title><abstract>Some abstract4</abstract></document>
</documents>
I am trying to write a ksh script to fetch the abstract value based on title=title4
xmllint , xstartlet is not allowed in my machine (access issues)
I have tried with
sed -n '/abstract/{s/.*<abstract>//;s/<\/abstract.*//;p;}' connections.xml
How to modify this to search based on a title
Based on the example you have given:
sed -n '/title>.*title4<\/title>/{s#.*<abstract>##;s#</abstract>.*##;p}' file
Will give you:
Some abstract4
grep approach:
grep -Poz '<title>.*?title4</title><abstract>\K[^<>]+(?=</abstract>)' connections.xml && echo ""
The output:
Some abstract4

how to improve this perl/bash one-liner to deserialize json data

I have a little bash program that calls a webservice that returns JSON data.
I have written the webservice program myself, I have complete control over its data sources, and thus I can trust the data that is returned.
Now I want to do something with the data.
The data is a simple, short key-value structure without nesting, and looks like this:
{
"asciifile" : "../tmp/data_20120720_105746-01580.txt",
"excelfile" : "../tmp/data_01580-20120720_105746.xlsx",
"from" : "Jun 19, 2012",
"msg" : "some info message, for the admin",
"outfile" : "data--recent.txt",
"outfile_excel" : "data--recent.txt.xlsx",
"resolution" : "std"
"to" : "Jul 20, 2012",
"url_comment" : "another info message, for the screen/user",
"url_outfile" : "http://www.example.com/path/tmp_cached_files/data--recent.txt",
"url_outfile_excel" : "http://www.example.com/path/tmp_cached_files/data--recent.txt.xlsx",
}
Now I am using this one-liner to deserialize the json structure returned to perl code. See last line of this snippet:
#!/bin/bash
cmd=$(curl_or_wget_call_to_webservice)
output=$(eval $cmd)
outfile_excel=$(echo "$output"| json_xs -f json -t dumper | tee | perl -n0777 -E 'eval "%h=%{$_}"; warn $# if $#; say $h{outfile_excel}')
For example, I'm not sure why I came up with the %{$_} construct. Is there a better way to do this? Is there a shorter way or a safer way to write the last line?
SE Editors: if you wish, you may move this post to the codereview stackexchange site, but I don't have an account there.
Edit: After revisiting the post after 8 months, I'd like to add that these days I use this one liner for getting the name of my github repos:
wget --quiet --auth-no-challenge --user knbknb --password secret -O -
https://api.github.com/user/repos |
perl -MJSON -n0777 -E '$r = decode_json($_); map {say $_->{name}} #$r' -
Perl can decode JSON itself, so the next should give some idea, using LWP::Simple to get some json data.
perl -MLWP::Simple -MJSON \
-e '$ref = decode_json(get("http://your.url/to/webservice")); print $ref->{outfile_excel}'
The $ref contains a perl structure of all JSON data, print out as you want it..
There is jshon. You could simply call something like
curl http://somehere.tld/data.json | jshon -e url_outfile_excel
Which would print the value for the given key.
By the way. Having control over the webservice doesn't make the input trustworthy. Be careful when calling eval.