I have tried this regex in centos
RegEx: echo 'select-value'|sed -r 's/(-)(\w)/\U\2/g'
Output: selectValue
But in alpine i am not getting the output when i tried the below regex
RegEx: echo 'select-value'|sed -r 's/(-)(\w)/\%U\2/g'
Output: select%Uvalue
Expected Output: selectValue
Please suggest the right regex.
Thanks
It seems that alpine uses the busybox sed by default. You have to install the gnu sed (it may be already installed).
In a docker alpine 3.5 container I've tried that one and it worked echo 'select-value'|/bin/sed -r 's/(-)(\w)/\U\2/g'. Mind the /bin/sed part. Gnu sed was already installed in the docker image.
If you have not luck with that you may use awk if available:
echo 'select-value-another-value'|awk -F'-' '{ for(i=1; i<=NF; i++) printf toupper(substr($i,1,1)) substr($i,2);printf "\n"}'
If you don't have to use sed, try perl:
$ echo 'select-value-but-not-that-one'|perl -pe 's/-(\w)/\u$1/g'
selectValueButNotThatOne
Related
I am trying to extract the version of a jdk using regular-expressions Actually I have the following version:
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
I wrote the regex. It looks like the following:
^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}$
This regular expression is working on the online regex tester (https://regex101.com/). Unfortunately, it is not working with grep-command. I am using the extended regular expression. My Code for the extraction of jdk-version look like the following:
CMD_RESULT=$(java --version 2>&1 | head -n 1 | cut -d '' -f 2)
if [ ! -z "$CMD_RESULT" ]
then
for token in $CMD_RESULT
do
JAVA_VERSION=$(echo $token | grep -e $VERSION_EXTRACTION_REGEX)
if [ ! -z $JAVA_VERSION ];
then
printf "${GREEN}Java version: [$JAVA_VERSION]\n"
fi
done
fi
I am not understanding, why my regex is working on the online regex checker, while it is not working with the grep-command. I am using the Parameter -e for extended regexp.
Any Idea ?
A few small changes to OPs current code:
as mentioned in the comments, ^ and $ represent the beginning and ending of the input; remove these from the regex
while grep can use the resulting regex it will be necessary to tell grep to run in -Extended regex mode
we can use grep's -o option to limit output to just the portion that matches the regex
Sample input data:
$ cat jdk.dat
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
One grep solution using OP's modified regex:
$ grep -oE '[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}' jdk.dat
11.0.9.1
11.0.9.1
11.0.9.1
Same thing but with the regex stored in OPs variable:
$ VERSION_EXTRACTION_REGEX='[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}'
$ grep -oE "${VERSION_EXTRACTION_REGEX}" jdk.dat
11.0.9.1
11.0.9.1
11.0.9.1
NOTE: I'll leave it up to the user to decide which value to use, eg, head -n 1 to work with just the first input line (openjdk 11.0.9.1 2020-11-04)
Be done with using only native Bash commands to parse the java version string:
#!/usr/bin/env bash
# Capture java command path if it exists OR exit fail
java_cmd=$(command -v java) || exit 1
# Capture java raw version output
java_raw_version=$("$java_cmd" -version 2>&1)
# Match java raw version string against Bash Regex OR dump debug if match fail
[[ $java_raw_version =~ ([0-9]+)\.([0-9]+)\.([0-9]+)[_.+-]([0-9]+) ]] ||
typeset -p java_raw_version BASH_REMATCH
major=${BASH_REMATCH[1]} # Regex capture group 1
minor=${BASH_REMATCH[2]} # Regex capture group 2
patch=${BASH_REMATCH[3]} # Regex capture group 3
release=${BASH_REMATCH[4]} # Regex capture group 4
# Recompose a semantic version string
semver="$major.$minor.$patch-$release"
printf 'Java semantic version is: %s\n' "$semver"
Sample outputs:
From:
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-8u275-b01-0ubuntu1~20.10-b01)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)
Output:
Java semantic version is: 1.8.0-275
From:
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
Output:
Java semantic version is: 11.0.9-1
About semantic versioning, see: https://semver.org/
Here is a very simple awk solution (no need for regexp):
#!/usr/bin/env bash
# Capture java command path if it exists OR exit fail
java_cmd=$(command -v java) || exit 1
# Capture java raw version output
java_raw_version=$("$java_cmd" -version 2>&1)
# print out the Java version:
echo $java_raw_version | awk -F \" 'NR==1{print "Java semantic version is: "$2}''
Explanation:
-F \" set awk fields separator to "
NR==1 only deal with line #1
print "Java semantic version is: "$2 append 2nd field to text and print
In my /etc/apt/sources.list I want to append to all non-comment lines "contrib non-free" using sed.
Here is my expression:
sed -n -i '/^\([^#].*main\)/{s/main/main contrib non-free/p}' /etc/apt/sources.list
It does what I want but it also removes all other lines.
What am I doing wrong?
Problem is with the option -n in your command that suppresses normal output. You need to remove -n and also remove p option from substitution to avoid double printing of matching lines.
This command should work for you:
sed -i '/^\([^#].*main\)/s/main/& contrib non-free/' /etc/apt/sources.list
The accepted answer from #anubhava (thanks for your code, as it pointed me in the right direction) would add contrib non-free even if it already exists in the line. Try the following:
sed -i '/^\([^#].*main\)*$/s/main/& contrib non-free/' /etc/apt/sources.list
I am trying to put together a simple script that does a regex on a git clone output and captions the directory that the default clone cmd is cloning too and then captures this into a shell for or something that can then be piped into xargs?
E.g:
git clone git#github.com:thorchain/instaswap-sdk.git |& grep "\'\S*\'" | xargs cd
In this example grep is not the right tool as its output is the matching line and not the match. However, for the life of me, I can't seem to find a simple regex matching tool?
Thanks in adv
Luke
Turns out the missing bit was the grep -o that I needed. What I was trying to do was built a bash function the git cloned and cd into the repos directory.
End solution here:
function gitc() {
cd `git clone "$#" |& grep -o "\'\S*\'" | tr -d "'"`
}
So I am writing a few scripts for migrating SVN to GIT, we have a bunch of "old" branches in SVN that still exist but don't need to be moved to GIT. (Branches which happened to have already been merged to trunk).
After a bit of google-fu I've come up with the following:
$(git for-each-ref --format='%(refname:short)' --merged origin/trunk | grep '(?!origin\/trunk)origin\/.*')
To be passed to
git branch -D --remote _previouscommandgoeshere_
If I run just git for-each-ref --format='%(refname:short)' --merged origin/trunk I get the following output:
origin/IR1091
origin/IR1102
origin/IR1105
...
origin/IR932
origin/Software
origin/trunk
origin/trunk#6792
origin/trunk#6850
When I add the grep command I get 0 values.
However, https://regexr.com/3ot1t has thaught me that my regexp is doing exactly what I want to do. Remove all branches except for the trunk branch.
What is wrong with the regexp/grep? (note I am not a linux/grep guru. This is all done in bash that comes with windows git)
The regexp is right, but grep by default does not support PCRE expression constructs like Negative look-ahead (?!. You need to enable the -P flag to enable the PCRE library, without that it just supports the Basic Regular Expression engine
.. | grep -oP '(?!origin\/trunk)origin\/.*'
Or use a perl regex match on the command line for which no flags need to be set up
.. | perl -ne 'print if /(?!origin\/trunk)origin\/.*/'
grep -P 'origin/(?!trunk)'
just this, can match what your wanted
All
I have following shell command working as per expectation on shell but not working when invoked inside perl
Shell command:
grep -P -s -irl --include \*.v "\s+hello\s?[(].*" <PATH>
working fine
Inside Perl:
$inst_search = `grep -P -s -irl --include \*.v "\s+$inst\s?[(].*" #plt_dirs`;
not working
I am suspecting i am missing something with regexp inside grep..please correct me !
Thanks,
Vivek
Perl will escape special shell characters when calling exec/system/qx (or backticks) with a string.
Try using the exec or system functions, but passing a list, e.g.
system('grep', '-P', '-s', '-irl', '--include', '\*.v', '"\s+hello\s?[(].*"', #plt_dirs);
You may also want to look at a module that does some of the error handling for you, like IPC::System::Simple.
Try this one:
$inst_search = qx#grep -P -s -irl --include \*.v "\s+$inst\s?[(].*" #plt_dirs#;
Or use any other non-alphanumeric character instead of "#"for quoting.