How to remove last n character from string in shell script [duplicate] - bash

This question already has answers here:
Extract filename and extension in Bash
(38 answers)
Closed 21 days ago.
I have a variable reponame in Shell Script(bash) holding a string
echo $reponame
"testrepo.git"
I want to remove the last 4 character of this string and assign the result to a new variable repo
echo $repo
"testrepo"
How can I do this?

If I understand correctly, you want to get rid of the .git extension. Then the correct expression would be
repo=${reponame%.*}
or
repo=${reponame%.git}
for that very specific case.
For substrings in general, the expression removing last 4 characters would go like
repo=${reponame:0:-4}
Very nice resource on Bash string operations:
https://tldp.org/LDP/abs/html/string-manipulation.html
For shell in general you might use various approaches such as
repo=$(echo -n "$reponame" | sed 's/\.git$//')
or
repo=$(echo -n "$reponame" | rev | cut -f 2- -d '.' | rev)

Related

How to add double quotation marks ("") around pipe-separated fields [duplicate]

This question already has answers here:
How can I add quotation marks to fields in a CSV file?
(4 answers)
Closed 2 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Let's say I have a file with this structure:
1|2|3|4|
5|6|7|8|
9|10|11|12|
However, I want my file to look like this (expected output):
"1"|"2"|"3"|"4"|
"5"|"6"|"7"|"8"|
"9"|"10"|"11"|"12"|
I am trying to used sed command in the following way:
sed 's/^/"/g'
Unfortunately, it only adds quotation marks at the beginning of each line:
"1|2|3|4|
"5|6|7|8|
"9|10|11|12|
^ means "the beginning of a line". Use [^|] instead which means "anything but |". If your implementation of sed supports +, you can use
sed -E 's/[^|]+/"&"/g'
otherwise, you need to be more verbose
sed 's/[^|][^|]*/"&"/g'
& represents the matched part.
You can use
sed -E 's/[^|]+/"&"/g' file > newfile
The -E option enables the POSIX ERE syntax and [^|]+ thus matches one or more chars other than |, and "&" replaces each with its copy enclosed with " on both sides.
See the online sed demo:
s='1|2|3|4|
5|6|7|8|
9|10|11|12|'
sed -E 's/[^|]+/"&"/g' <<< "$s"
Output:
"1"|"2"|"3"|"4"|
"5"|"6"|"7"|"8"|
"9"|"10"|"11"|"12"|
Here is a gnu awk way of doing the same:
awk -v RS="[|\n]+" '{ORS=RT; print "\"" $0 "\""}' file
"1"|"2"|"3"|"4"|
"5"|"6"|"7"|"8"|
"9"|"10"|"11"|"12"|

Extract flag and its value from string [duplicate]

This question already has answers here:
How do I parse command line arguments in Bash?
(40 answers)
Closed 4 years ago.
I want to be able to extract a flag (-q) and its value from a string. An example:
<string1> -q <value> <string2>
Here, <string1> and <string2> can contain any set of characters. To clarify <string1> and <string2> are placeholders for any possible string.
I want two things:
Be able to get the string
<string1> <string2>
Be able to get the string <value>
I would also be able to do something similar for this input:
<string1> --all <string2>
where --all is extracted and <string1> <string2> is is kept.
Unlike the proposed solution in How do I parse command line arguments in Bash?, I want to be able to extract a flag and its value and then keep the original command line input without the flag and that value.
A quick and very simple solution using cut:
echo "<string1> -q value <string2>" | cut -d'>' -f2 | cut -d'<' -f1
outputs : -q value
NOTE this only works if whatever is between your string1 / string2 tags does not contain <>

Using grep to filter real time output of a process? If so, how to get the line after a match? [duplicate]

This question already has answers here:
How to show only next line after the matched one?
(14 answers)
grep: show lines surrounding each match
(14 answers)
Read from a endless pipe bash [duplicate]
(1 answer)
Closed 4 years ago.
Should I use grep to filter a real time output? I'm not sure if this is what I should use for a real time output.
Example: command -option | grep --color 'string1\|string2'
If so, how to get also the lines after string1 and string2?
As #shellter mentioned, from man grep:
-A num, --after-context=num
Print num lines of trailing context after each match. See also the -B and -C options.
so you would use command -option | grep -A 1 --color 'string1\|string2' to print matched lines and the line right after them.
There are plenty of other options in the manual for grep, and most other command-line programs, so I suggest getting used to running man cmd as a quick first check.

Bash - Echo is splitting my string result [duplicate]

This question already has answers here:
How to remove a newline from a string in Bash
(11 answers)
Closed 4 years ago.
I have the following:
VERSION=$(curl -Is https://qa.me.com.br | sed -n '/^x-powered-by:/Ip' | sed '/x-powered-by:/I s/x-powered-by: //Ig')
Expected variable result (but it has one more character that broke my result):
MEWeb - QA - 267_4_2548
After, I'm showing by the following:
echo "##teamcity[progressMessage 'Version is $VERSION']"
Expected (without '*'):
*##teamcity[progressMessage 'Version is MEWeb - QA - 267_4_2548']
Actual:
']##teamcity[progressMessage 'Version is MEWeb - QA - 267_4_2548
I don't know what is breaking my result.
Thanks for help and sorry for my english!
Add
| tr -d '\r'
to the end of the curl command (just before the ")").
The response has a carriage return.
When you get the VERSION, put it in a file.
echo $VERSION > test.txt
Now, to see the hidden characters, use:
cat -v test.txt
You'll see:
MEWeb - QA - 267_4_2548**^M**
You need to handle that character, which is causing the trouble.

Returning only a part of the string from a grep result [duplicate]

This question already has answers here:
Can grep show only words that match search pattern?
(15 answers)
Closed 6 years ago.
I'm using grep on text file containing some simple logs in the following form:-
[ABC.txt]
1=abc|2=def|3=ghi|4=hjk|5=lmn|6=opq
8=rst|9=uvx|10=wyz
.
.
.
.
and so on
the values for the tags 1,2,3,4 etc are different throughout the file and include special characters in some case too. Is there a way I can only retrieve the value for the tag 4 and no other tags via GREP?
BTW,this log file is itself a result of grep .So please advice if I should redirect the output first and then apply the second grep or apply the second grep over the first one,considering it's a large file.
grep -Po '(?<=4=)[^|]*' ABC.txt
You could pipe the result of grep to cut, split the fields by "|" and select the fourth field
[your grep command] | cut -d | -f 4
If you want the "4=" to be gone you can just do the same by using cut a second time but this time using "=" as a delimiter.
http://pubs.opengroup.org/onlinepubs/009695399/utilities/cut.html

Resources