Linux - Find a string and get the next section - linux

If I have a string like "name":"tempname","department":"tempdept", I want to search for the value for "department" which is "tempdept". So if "department" exists, I need just the value returned. The length of the string that is searched can be very long. Is this possible using sed/awk, can you please help?
I tried the following, but it returns the whole string. I am searching for department here.
echo $data | sed 's/\(\"department\":\)\(.*\"\)/\2/'

Some simple solutions:
echo "$data" | tr , \\n | awk -F: '$1 ~ /^department$/{ print $2 }'
or
echo "$data" | awk -F: '$1 ~ /^department$/{ print $2 }' RS=,
Your solution just need minor modifications:
echo "$data" | tr , \\n | sed -n 's/"department":\(.*\)/\2/p'
or
echo "$data" | tr , \\n | sed -n '/"department":/s///p'

See if this does it for you:
sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/\1/;p;}'
Example:
echo '"name":"tempname","department":"tempdept"' | sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/\1/;p;}'
tempdept
If you need to retain the double quotes, just add them back in during the replacement:
sed -ne '/"department"/{s/^.*"department":"\([^"]*\).*/"\1"/;p;}

Related

Strip a part of string in linux

Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 is my string and the result I want is vm-1.0.3
What is the best way to do this
Below is what I tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1,$2'}
vm 1.0.3
I also tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1"-",$2'}
vm- 1.0.3
Here I do not need space in between
I tried using cut and I got the expected result
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | cut -c 1-8
vm-1.0.3
What is the best way to do the same?
Making assumptions from the 1 example you provided about what the general form of your input will be so it can handle that robustly, using any sed:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
sed 's/^[^-]*-[^-]*-[^_]*_\(.*\)-[^-]*$/\1/'
vm-1.0.3
or any awk:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
awk 'sub(/^[^-]+-[^-]+-[^_]+_/,"") && sub(/-[^-]+$/,"")'
vm-1.0.3
You don't need 2 calls to awk, but your syntax with the single quotes outside the curly's, including printing the hyphen:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk -F_ '{print $2}' | awk -F- '{print $1 "-" $2}'
If your string has the same format, let the field separator be either - or _
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F"[-_]" '{print $4 "-" $5}'
Or split the second field on - and print the first 2 parts
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F_ '{
split($2,a,"-")
print a[1] "-" a[2]
}'
Or with gnu-awk a bit more specific match with a capture group:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk 'match($0, /^Apps-[^_]*_(vm-[0-9]+\.[0-9]+\.[0-9]+)/, a) {print a[1]}'
Output
vm-1.0.3
This is the easiest I can think of:
echo "Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2" | cut -c 25-32
Obviously you need to be sure about the location of your characters. In top of that, you seem to be have two separators: '_' and '-', while both characters also are part of the name of your entry.
echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' | sed -E 's/^.*_vm-([0-9]+).([0-9]+).([0-9]+)-.*/vm-\1.\2.\3/'

How to search and delete a pattern from a line?

I need to write a simple bash script that takes a text line
some-pattern something-else
and erases some-pattern and returns only something-else. I wrote a script to do the opposite with grep -o, but I don't know how I could do with this case. Any help is very much appreciated.
sample input:
"SNMPv2::sysLocation.0 = STRING: someLocation"
Desired Output:
"someLocation"
Considering " are NOT in your sample Input_file and expected output, could you please try following with GNU grep.
grep -oP '.*STRING: \K(.*)' Input_file
someLocation
For \K explanation:
\K is a PCRE extension to regex syntax discarding content prior to
that point from being included in match output
You can use sed to delete the part in front of what you want to keep.
Given:
$ echo "$s"
"SNMPv2::sysLocation.0 = STRING: someLocation"
You can do:
$ echo "$s" | sed -nE 's/^.*(someLocation)/\1/p'
someLocation
And if you want to add quotes:
$ echo "$s" | sed -nE 's/^.*(someLocation)/"\1"/p'
"someLocation"
If the portion after STRING: is variable, not fixed, you can use STRING: and the capture anchor:
$ echo "$s" | sed -nE 's/^.*STRING:[[:space:]]*(.*)/"\1"/p'
"someLocation"
Or, sed to capture and print the last word after the last space:
$ echo "$s" | sed -nE 's/([^[:space:]]*$)/\1/p'
You can also use awk if the last word is space separated from the other fields:
$ echo "$s" | awk '{print $NF}'
Or a pipeline with cut and rev works too:
$ echo "$s" | rev | cut -d' ' -f 1 | rev
You can use: echo ${STRING} | awk -F" " '/someLocation/ { print $NF }'
-F will use space (represented by double-quotes with space between them) as separator; /someLocation/ will search for your location; { print $NF } will show the last part of your string (which, I believe, is the place where location is.

grep for contents after pattern for word character and comma

echo "this is a test:foo,bar,baz']" | grep -o -E "test:.*" | awk -F: '{ print $2 }'
foo,bar,baz']
I get '] printed at the end, how to print only the word characters and common, nothing else, in this case I need to extract only foo,bar,baz
You can use a single awk for this:
echo "this is a test:foo,bar,baz']" | awk -F 'test:' '{sub(/[^,[:alnum:]].*/, "", $2); print $2}'
foo,bar,baz
Or, you can use a single sed:
echo "this is a test:foo,bar,baz']" | sed 's/.*test://; s/[^,[:alnum:]].*//'
foo,bar,baz
echo "this is a test:foo,bar,baz']"| awk -F: '{sub(/baz../,"baz"); print $2}'
outputs
foo,bar,baz
Using gnu grep pearl regex
$ echo "this is a test:foo,bar,baz']" | grep -oP "(?<=test:)(\w,*)+"
foo,bar,baz

How to extract words between two characters in linux?

I have the following stored in a file named tmp.txt
user/config/jars/content-config-factory-3.2.0.0.jar
I need to store this word to a variable -
$variable=content-config-factory
I have written the following
while read line
do
var=$(echo $line | awk 'BEGIN{FS="\/"; OFS=" "} {print $NF}' )
var=$(echo $var | awk 'BEGIN{FS="-"; OFS=" "} {print $(1)}' )
echo $var
done < tmp.txt
This returns the result "content" instead of "content-config-factory".
Can anyone please tell me how to extract a word between two characters from a string efficiently.
An awk solution would be like
awk -F/ '{sub("-[^-]+$", "", $NF); print $NF}
Test
$ echo "user/config/jars/content-config-factory-3.2.0.0.jar" | awk -F/ '{sub("-[^-]+$", "", $NF); print $NF}'
content-config-factory
You can try this way also and get your expected result
variable=$(sed 's:.*/\(.*\)-.*:\1:' FileName)
echo $variable
OutPut :
content-config-factory
You could use grep,
grep -oP '(?<=/)[^/]*(?=-\d+\.)' file
Example:
$ var=$(echo 'user/config/jars/content-config-factory-3.2.0.0.jar' | grep -oP '(?<=/)[^/]*(?=-\d+\.)')
$ echo "$var"
content-config-factory

How to use sed on Linux to get values from file name?

how to retrive every portion separately from following file name? DSA4020_frontcover_20346501_2011-05.doc
I want to retrieve informations as below;
name = DSA4020
type = frontcover
id = 20346501
date = 2011-05
is it possible to do with sed??
Yes, you can:
pax$ echo 'DSA4020_frontcover_20346501_2011-05.doc' | sed
-e 's/^/name=/'
-e 's/_/\ntype=/'
-e 's/_/\nid=/'
-e 's/_/\ndate=/'
-e 's/\..*//'
name=DSA4020
type=frontcover
id=20346501
date=2011-05
That's all on one line, I've just split it for readability.
You could also do it with awk if you wish:
pax$ echo 'DSA4020_frontcover_20346501_2011-05.doc'
| awk -F_ '{print "name="$1"\ntype="$2"\nid="$3"\ndate="substr($4,1,7)}'
name=DSA4020
type=frontcover
id=20346501
date=2011-05
awk may be a better choice
# f=DSA4020_frontcover_20346501_2011-05.doc
# name=$(echo $f | awk -F_ '{print $1}')
# echo $name
DSA4020
# type=$(echo $f | awk -F_ '{print $2}')
# echo $type
frontcover
In pure bash
FILE="DSA4020_frontcover_20346501_2011-05.doc"
eval $(echo $FILE |(IFS="_";read a b c d; echo "name=$a;type=$b;id=$c;date=${d%.doc}"))
echo Name:$name Type:$type ID:$id DATE:$date

Resources