Print only the contents after a certain pattern match - bash

I have a string like this:
query:schema:query_result{cell=ab}: <timestamp>
I'd like to just print the ab and assign it to a variable. How can I do this with grep/sed?

You may try his,
$ var=$(grep -oP '=\K\w+' <<< "$str")
or
$ sed 's/.*=\(\w\+\).*/\1/' <<<"$var"
ab

You can also use awk:
s='query:schema:query_result{cell=ab}: <timestamp>'
awk -F '[=}]' '{print $2}' <<< "$s"
ab
To assign it to a variable:
var="$(awk -F '[=}]' '{print $2}' <<< "$s")"

Related

Get only numbers in output

I need to get only numbers from this:
release/M_0.1.0
thus, need to extract with bash to have in output this:
0.1.0.
I have tried this but cannot finish it:
echo "release/M_0.1.0" | awk -F'/' '{print $2}'
And what about if given such string? relea234se/sdf23_4Mm0.1.0.8. How to get only 0.1.0.8? Please pay attention that this can be random digits such as 0.2 or 1.9.1.
Please check if this grep command works
echo "release/M_0.1.0" | egrep -o '[0-9.]+'
You could also use general parameter expansion parsing to literally remove characters up through the last that isn't digits or dots.
$: ver() { echo "${1//*[^.0-9]/}"; }
$: ver release/M_0.1.0
0.1.0
$: ver relea234se/sdf23_4Mm0.1.0.8
0.1.0.8
With sed you can do:
echo "release/M_0.1.0" | sed 's#.*_##'
Output:
0.1.0
Considering that your Input_file will be same as shown samples.
echo "$var" | awk -F'_' '{print $2}'
OR could use sub:
echo "$var" | awk '{sub(/.*_/,"")} 1'
With simple bash you could use:
echo "${var#*_}"
echo release/M_0.1.0 | awk -F\_ '{print $2}'
0.1.0
Take your pick:
$ var='relea234se/sdf23_4Mm0.1.0.8'
$ [[ $var =~ .*[^0-9.](.*) ]] && echo "${BASH_REMATCH[1]}"
0.1.0.8
$ echo "$var" | sed 's/.*[^0-9.]//'
0.1.0.8
$ echo "$var" | awk -F'[^0-9.]' '{print $NF}'
0.1.0.8
if data in d file, tried on gnu sed:
sed -E 's/relea.*/.*([0-9][0-9.]*)$/\1/' d

Remove a word from a string bash

I have the string
file="this-is-a-{test}file"
I want to remove {test} from this string.
I used
echo $file | sed 's/[{][^}]*//'
but this returned me
this-is-a-}file
How can I remove } too?
Thanks
Also try this bash only oneliner as an alternative:
s="this-is-a-{test}file"
echo ${s/\{test\}/}
You can use sed with correct regex:
s="this-is-a-{test}file"
sed 's/{[^}]*}//' <<< "$s"
this-is-a-file
Or this awk:
awk -F '{[^}]*}' '{print $1 $2}' <<< "$s"
this-is-a-file

shortening headers using awk

I have headers like
>XX|6226515|new|xx_000000.1| XXXXXXX
in a text file which I am trying shorten to
>XX6226515
using awk. I tried
awk -F"|" '/>/{$0=">"$1}1' input.txt > output.txt
but it yields the following instead
>XX|6226515|new|
awk -F"|" '{print $1$2}' input.txt > output.txt
Output:
>XX6226515
sed solution:
sed -e 's/|//' -e 's/|.*//'
The first substitution removes the first vertical bar, the second one removes the second one and anything after it.
$ awk -F'|' '$0=$1$2' <<< ">XX|6226515|new|xx_000000.1| XXXXXXX"
>XX6226515
This cut can also make it:
cut -d"|" --output-delimiter="" -f-2
See output:
$ echo ">XX|6226515|new|xx_000000.1| XXXXXXX" | cut -d"|" --output-delimiter="" -f-2
>XX6226515
-d"|" sets | as field delimiter.
--output-delimiter="" indicates that the output delimiter has to be empty.
-f-2 indicates that it has to print all records up to the 2nd (inclusive).
Also with just bash:
while IFS="|" read a b _
do
echo "$a$b"
done <<< ">XX|6226515|new|xx_000000.1| XXXXXXX"
See output:
$ while IFS="|" read a b _; do echo "$a$b"; done <<< ">XX|6226515|new|xx_000000.1| XXXXXXX"
>XX6226515

How to print all columns but last 2?

How to print all columns but last 2?
e.g
input :echo FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008
output : FB_SYS_0032_I03_LTO3_idaen02r_02
delimiter : _ (underscore)
for your example, this awk one liner should do:
awk -F'_' -v OFS='_' 'NF-=2' file
test:
kent$  awk -F'_' -v OFS='_' 'NF-=2' <<< "FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008"
FB_SYS_0032_I03_LTO3_idaen02r_02
Just use an RE that describes the last 2 fields:
awk '{sub(/_[^_]*_[^_]*$/,"")}1'
or:
sed 's/_[^_]*_[^_]*$//'
e.g.:
$ echo FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008 | awk '{sub(/_[^_]*_[^_]*$/,"")}1'
FB_SYS_0032_I03_LTO3_idaen02r_02
$ echo FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008 | sed 's/_[^_]*_[^_]*$//'
FB_SYS_0032_I03_LTO3_idaen02r_02
Te above will work with any modern awk and any sed on any system.
use this awk command:
awk -F "_" '{for (i=1; i<=NF-2; i++) {printf ("%s", $i); if (i<NF-2) printf "_"} print ""}'
FB_SYS_0032_I03_LTO3_idaen02r_02
Using sed:
sed -r 's/(_[^_]*){2}$//'
For example,
$ echo 1_2_3_4_5 | sed -r 's/(_[^_]*){2}$//'
1_2_3
$ echo 1_2_3_4 | sed -r 's/(_[^_]*){2}$//'
1_2
$ echo FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008 | sed -r 's/(_[^_]*){2}$//'
FB_SYS_0032_I03_LTO3_idaen02r_02
Probably this is the simplest way:
$ input="FB_SYS_0032_I03_LTO3_idaen02r_02_20130820_181008"
$ echo "${input%_*_*}"
FB_SYS_0032_I03_LTO3_idaen02r_02

get the file name from the path

I have a file file.txt having the following structure:-
./a/b/c/sdsd.c
./sdf/sdf/wer/saf/poi.c
./asd/wer/asdf/kljl.c
./wer/asdfo/wer/asf/asdf/hj.c
How can I get only the c file names from the path.
i.e., my output will be
sdsd.c
poi.c
kljl.c
hj.c
You can do this simpy with using awk.
set field seperator FS="/" and $NF will print the last field of every record.
awk 'BEGIN{FS="/"} {print $NF}' file.txt
or
awk -F/ '{print $NF}' file.txt
Or, you can do with cut and unix command rev like this
rev file.txt | cut -d '/' -f1 | rev
You can use basename command:
basename /a/b/c/sdsd.c
will give you sdsd.c
For a list of files in file.txt, this will do:
while IFS= read -r line; do basename "$line"; done < file.txt
Using sed:
$ sed 's|.*/||g' file
sdsd.c
poi.c
kljl.c
hj.c
The most simple one ($NF is the last column of current line):
awk -F/ '{print $NF}' file.txt
or using bash & parameter expansion:
while read file; do echo "${file##*/}"; done < file.txt
or bash with basename :
while read file; do basename "$file"; done < file.txt
OUTPUT
sdsd.c
poi.c
kljl.c
hj.c
Perl solution:
perl -F/ -ane 'print $F[#F-1]' your_file
Also you can use sed:
sed 's/.*[/]//g' your_file

Resources