How to extract content between braces using grep? - grep

I would like to use grep to extract only one part between braces
My log file :*
{
* "path": "/root/power.doc"
}
How to extract content between braces ?

grep doesn't do ranges. You could use awk instead:
awk '/\{/,/\}/ {if($0 ~ /path/){print $0}}' kylian.log
* "path": "/root/power.doc"
EDIT 1:
Here a modified file for testing:
$ cat kylian.log
* "path": "/root/power_before.doc"
--- before
+++ after
## -1,4 +1,4 ##
{
* - "mode": "0010",
* + "mode": "0030",
* "path": "/root/power.doc"
}
* "path": "/root/power_after.doc"
And here the output when I run my awk against it:
$ awk '/\{/,/\}/ {if( $0 ~ /path/){print $0}}' kylian.log
* "path": "/root/power.doc"

Related

How can I combine two lists in Nix?

I've currently got a list defined as:
environment.systemPackages = with pkgs; [
acpi
ag
alacritty
audacity
awscli
bash
breeze-gtk
cabal-install
];
How would I go about defining two lists and then merging them to set the environment.systemPackages value?
I'd like to split the list so it's easier to manage groups of related packages.
https://nixos.org/manual/nix/stable/expressions/language-operators.html
The ++ operator:
nix-repl> [1 2 3] ++ [5 6]
[ 1 2 3 5 6 ]
Code example:
let
unstable = import <unstable> {
config = config.nixpkgs.config;
};
examplePkgs = with pkgs; [
bash
];
in
{
environment.systemPackages = with pkgs; [
google-chrome
]
++ examplePkgs;

Expected any character but end of input found

my input is a recursive structure looks like this (notice the blank 2nd line):
xxx #{} yyy #{ zzz #{} wwww }
the grammar as i see that would read it should look like this:
start = item+
item = thing / space
thing = '#{' item* '}'
space = (!'#' .)+
but what i get is
Line 2, column 1: Expected "#{", "}", or any character but end of input found.
what am i doing wrong?
I do not know peg at all, but a quick look at the docs seems to say the dot in the 4th rule is the problem. The online parser succeeds with:
start = item+
item = thing / space
thing = '#{' item* '}'
space = [ a-z]+
This produces:
[
[
"x",
"x",
"x",
" "
],
[
"#{",
[],
"}"
],
[
" ",
"y",
"y",
"y",
" "
],
[
"#{",
[
[
" ",
"z",
"z",
"z",
" "
],
[
"#{",
[],
"}"
],
[
" ",
"w",
"w",
"w",
"w",
" "
]
],
"}"
]
]
In order to make it run, I modified the code as:
start = item+
item = thing / space
thing = '#{' item* '}'
space =[^#}]+

create GeoJSON for loop used?

create JSON file
Here I want to use the min and max of x and y, then I have 4 points for the polygon. But how to loop through precinct?
And I cannot get the JSON working.
z.sub <- subset(z, (z$Violation.Precinct %in% police.precincts))
z.long.min <- NULL
z.long.max <- NULL
z.lat.min <- NULL
z.lat.max <- NULL
### find coordinates for each precinct
for(i in 1:length(police.precincts)){
z.long.min[i] <- min(hulls[hulls$Violation.Precinct == police.precincts[i],]$x)
z.long.max[i] <- max(hulls[hulls$Violation.Precinct == police.precincts[i],]$x)
z.lat.min[i] <- min(hulls[hulls$Violation.Precinct == police.precincts[i],]$y)
z.lat.max[i] <- max(hulls[hulls$Violation.Precinct == police.precincts[i],]$y)
}
s <- {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[z.long.min[1], z.lat.min[1]], [z.long.min[1], z.lat.max[1]], [z.long.max[1], z.lat.min[1]], [z.long.max[1], z.lat.max[1]], [z.long.min[1], z.long.max[1]]
]
]
},
"properties": {
"precinct": 1
}
}
}

separate 8th field

I could not separate my file:
chr2 215672546 rs6435862 G T 54.00 LowDP;sb DP=10;TI=NM_000465;GI=BARD1;FC=Silent ... ...
I would like to print first seven fields and from 8th field print just DP=10 and GI=BARD1. DP in GI info is always in 8th field. Fields are continue (...) so 8th field is not last.
I know how to extract 8th field :
awk '{print $8}' PLZ-10_S2.vcf | awk -F ";" '/DP/ {OFS="\t"} {print $1}'
of course how to extract first seven fields, but how to pipe it together? Between all fields is tab.
If DP= and GI= are always in the same position within $8:
$ awk 'BEGIN{FS=OFS="\t"} {split($8,a,/;/); $8=a[1]";"a[3]} 1' file
chr2 215672546 rs6435862 G T 54.00 LowDP;sb DP=10;GI=BARD1 ... ...
If not:
$ awk 'BEGIN{FS=OFS="\t"} {split($8,a,/;/); $8=""; for (i=1;i in a;i++) $8 = $8 (a[i] ~ /^(DP|GI)=/ ? ($8?";":"") a[i] : "")} 1' file
chr2 215672546 rs6435862 G T 54.00 LowDP;sb DP=10;GI=BARD1 ... ...
One way is to split() with semicolon the eight field and traverse all results to check which of them begin with DP or GI:
awk '
BEGIN { FS = OFS = "\t" }
{
split( $8, arr8, /;/ )
$8 = ""
for ( i = 1; i <= length(arr8); i++ ) {
if ( arr8[i] ~ /^(DP|GI)/ ) {
$8 = $8 arr8[i] ";"
}
}
$8 = substr( $8, 1, length($8) - 1 )
print $0
}
' infile
It yields:
chr2 215672546 rs6435862 G T 54.00 LowDP;sb DP=10;GI=BARD1 ... ...

How to use some text processing(awk etc..) to put some character in a text file at certain lines

I have a text file which has hex values, one value on one separate line. A file has many such values one below another. I need to do some analysis of the values for which i need to but some kind of delimiter/marker say a '#' in this file before line numbers 32,47,62,77... difference between two line numbers in this patterin is 15 always.
I am trying to do it using awk. I tried few things but didnt work.
What is the command in awk to do it?
Any other solution involving some other language/script/tool is also welcome.
Thank you.
-AD
This is how you can use AWK for it,
awk 'BEGIN{ i=0; } \
{if (FNR<31) {print $0} \
else {i++; if (i%15) {print $0} else {printf "#%s\n",$0}}\
}' inputfile.txt > outputfile.txt
How it works,
BEGIN sets an iterator for counting from your starting line 32
FNR<31 starts counting from the 31st record (the next record needs a #)
input lines are called records and FNR is an AWK variable that counts them
Once we start counting, the i%15 prefixes a # on every 15th line
$0 prints the record (the line) as is
You can type all the text with white spaces skipping the trailing '\' on a single command line.
Or, you can use it as an AWK file,
# File: comment.awk
BEGIN{ i=0; }
$0 ~ {\
if (FNR<31) {print $0} \
else {\
i++; \
if (i%15) {\
print $0
}\
else {\
printf "#%s\n",$0
}\
}\
}
And run it as,
awk -f comment.awk inputfile.txt > outputfile.txt
Hope this will help you to use more AWK.
Python:
f_in = open("file.txt")
f_out = open("file_out.txt","w")
offset = 4 # 0 <= offset < 15 ; first marker after fourth line in this example
for num,line in enumerate(f_in):
if not (num-offset) % 15:
f_out.write("#\n")
f_out.write(line)
Haskell:
offset = 31;
chunk_size = 15;
main = do
{
(h, t) <- fmap (splitAt offset . lines) getContents;
mapM_ putStrLn h;
mapM_ ((putStrLn "#" >>) . mapM_ putStrLn) $
map (take chunk_size) $
takeWhile (not . null) $
iterate (drop chunk_size) t;
}

Resources