Remove a word from a string bash - 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

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

Extract all ip addresses with sed and awk from a string

It is simple to extract all ip addresses with grep from a string.
string="221.11.165.237xxxx221.11.165.233\n
219.158.9.97ttttt219.158.19.137"
echo $string |grep -oP "(\d+\.){3}\d+"
221.11.165.237
221.11.165.233
219.158.9.97
219.158.19.137
The regrex pattern is simple (\d+\.){3}\d+.
Do the same job with sed and awk.
For sed:
echo $string | sed 's/^\(\(\d\+\.\)\{3\}\d\+\)$/\1/g'
221.11.165.237xxxx221.11.165.233\n 219.158.9.97ttttt219.158.19.137
For awk:
echo $string |gawk 'match($0,/(\d+\.){3}\d+/,k){print k}'
echo $string |awk '/(\d+\.){3}\d+/{print}'
How to fix it for sed and gawk(awk)?
The expect output is the same as grep.
221.11.165.237
221.11.165.233
219.158.9.97
219.158.19.137
Very few tools will recognize \d as meaning digits. Just use [0-9] or [[:digit:]] instead:
$ echo "$string" | awk -v RS='([0-9]+\\.){3}[0-9]+' 'RT{print RT}'
221.11.165.237
221.11.165.233
219.158.9.97
219.158.19.137
The above uses GNU awk for multi-char RS and RT. With any awk:
$ echo "$string" | awk '{while ( match($0,/([0-9]+\.){3}[0-9]+/) ) { print substr($0,RSTART,RLENGTH); $0=substr($0,RSTART+RLENGTH) } }'
221.11.165.237
221.11.165.233
219.158.9.97
219.158.19.137
This might work for you (GNU sed):
sed '/\n/!s/[0-9.]\+/\n&\n/;/^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\n/P;D' file
Insert newlines either side of strings consisting only of numbers and periods. If a line contains only an IP address print it.
An easier-on-the-eye rendition uses the -r option:
sed -r '/\n/!s/[0-9.]+/\n&\n/;/^([0-9]{1,3}\.){3}[0-9]{1,3}\n/P;D' <<<"$string"
As you weren't specific about what could be between the ip addresses, I went with the fact that only numbers and periods will be in the ip:
echo "$string" | sed -r 's/[^0-9.]+/\n/'
echo "$string" | awk '1' RS="[^0-9.]+"

Print only the contents after a certain pattern match

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")"

How to group each 2 column together and chage the separator type between them?

Input:
echo "1021,fra,1022,eng,1023,qad" | sed or awk ...
Expected output:
1021-fra,1022-eng,1023-gad
echo "1021,fra,1022,eng,1023,qad" |sed 's/\([^,][^,]*\),\([^,][^,]*\)/\1-\2/g'
1021-fra,1022-eng,1023-qad
by GNU sed
echo "1021,fra,1022,eng,1023,qad" |sed -r 's/([^,]+),([^,]+)/\1-\2/g'
Here's one way to do it, with a little cheat:
echo "1021,fra,1022,eng,1023,qad" | sed -e 's/,\([a-z]\)/-\1/g'
That is, replace every comma followed by a letter with a hyphen followed by that letter.
In case it helps, here's another version cheating a bit differently:
echo "1021,fra,1022,eng,1023,qad" | sed -e 's/\([0-9]\),/\1-/g'
That is, replace every digit followed by a comma with that digit and a hyphen.
Here is an awk version:
echo "1021,fra,1022,eng,1023,qad" | awk -F, '{for (i=1;i<NF;i++) printf "%s%s",$i,(i%2?"-":",");print $NF}'
1021-fra,1022-eng,1023-qad

Split String in Unix Shell Script

I have a String like this
//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
and want to get last part of
00000000957481f9-08d035805a5c94bf
Let's say you have
text="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
If you know the position, i.e. in this case the 9th, you can go with
echo "$text" | cut -d'/' -f9
However, if this is dynamic and your want to split at "/", it's safer to go with:
echo "${text##*/}"
This removes everything from the beginning to the last occurrence of "/" and should be the shortest form to do it.
For more information on this see: Bash Reference manual
For more information on cut see: cut man page
The tool basename does exactly that:
$ basename //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
00000000957481f9-08d035805a5c94bf
I would use bash string function:
$ string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
$ echo "${string##*/}"
00000000957481f9-08d035805a5c94bf
But following are some other options:
$ awk -F'/' '$0=$NF' <<< "$string"
00000000957481f9-08d035805a5c94bf
$ sed 's#.*/##g' <<< "$string"
00000000957481f9-08d035805a5c94bf
Note: <<< is herestring notation. They do not create a subshell, however, they are NOT portable to POSIX sh (as implemented by shells such as ash or dash).
In case you want more than just the last part of the path,
you could do something like this:
echo $PWD | rev | cut -d'/' -f1-2 | rev
You can use this BASH regex:
s='//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf'
[[ "$s" =~ [^/]+$ ]] && echo "${BASH_REMATCH[0]}"
00000000957481f9-08d035805a5c94bf
This can be done easily in awk:
string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
echo "${string}" | awk -v FS="/" '{ print $NF }'
Use "/" as field separator and print the last field.
You can try this...
echo //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf |awk -F "/" '{print $NF}'

Resources