Extract substring in bash
Extract substring in bash
Looking for a solution in bash (will be part of a script).
Given a filename in the form "someletters_12345_moreleters.ext", I want to extract the 5 digits and put them into a variable.
So to emphasize the point. I have a filename with x number of characters then a five digit sequence surrounded by a single underscore on either side then another set of x number of characters. I want to take the 5 digit number and put that into a variable.
I am very interested in the number of different ways that this can be accomplished. As with most things, I am sure there are a number of different ways to tackle this problem.
Answer by FerranB for Extract substring in bash
Use cut:
echo 'someletters_12345_moreleters.ext' | cut -d'_' -f 2
More generic:
INPUT='someletters_12345_moreleters.ext' SUBSTRING=$(echo $INPUT| cut -d'_' -f 2) echo $SUBSTRING
Answer by Johannes Schaub - litb for Extract substring in bash
Generic solution where the number can be anywhere in the filename, using the first of such sequences:
number=$(echo $filename | egrep -o '[[:digit:]]{5}' | head -n1)
Another solution to extract exactly a part of a variable:
number=${filename:offset:length}
If your filename always have the format stuff_digits_...
you can use awk:
number=$(echo $filename | awk -F _ '{ print $2 }')
Yet another solution to remove everything except digits, use
number=$(echo $filename | tr -cd '[[:digit:]]')
Answer by jor for Extract substring in bash
There's also the bash builtin 'expr' command:
INPUT="someletters_12345_moreleters.ext" SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)_.*' ` echo $SUBSTRING
Answer by PEZ for Extract substring in bash
Building on jor's answer (which doesn't work for me):
substring=$(expr "$filename" : '.*_\([^_]*\)_.*')
Answer by JB. for Extract substring in bash
If x is constant, the following parameter expansion performs substring extraction:
b=${a:12:5}
If the underscores around the digits are the only ones in the input, you can strip prefix and suffix off in two steps:
tmp=${a#*_} b=${tmp%_*}
If there are other underscores, it's probably feasible anyway, albeit more tricky. If anyone knows how to perform both expansions in a single expression, I'd like to know too.
Both solutions presented are pure bash, with no process spawning involved, hence very fast.
Answer by Darron for Extract substring in bash
Without any sub-processes you can:
shopt -s extglob front=${input%%_+([a-zA-Z]).*} digits=${front##+([a-zA-Z])_}
A very small variant of this will also work in ksh93.
Answer by nicerobot for Extract substring in bash
Here's how i'd do it:
FN=someletters_12345_moreleters.ext [[ $FN =~ _([[:digit:]]{5})_ ]] && NUM=${BASH_REMATCH[1]}
Note: the above is a regular expression and is restricted to your specific scenario of five digits surrounded by underscores. Change the regular expression if you need different matching.
Answer by brown.2179 for Extract substring in bash
just try to use cut -c startIndx-stopIndx
Answer by codist for Extract substring in bash
Here's a prefix-suffix solution (similar to the solutions given by JB and Darron) that matches the first block of digits and does not depend on the surrounding underscores:
str='someletters_12345_morele34ters.ext' s1="${str#"${str%%[[:digit:]]*}"}" # strip off non-digit prefix from str s2="${s1%%[^[:digit:]]*}" # strip off non-digit suffix from s1 echo "$s2" # 12345
Answer by jperelli for Extract substring in bash
In case someone wants more rigorous information, you can also search it in man bash like this
$ man bash [press return key] /substring [press return key] [press "n" key] [press "n" key] [press "n" key] [press "n" key]
Result:
${parameter:offset} ${parameter:offset:length} Substring Expansion. Expands to up to length characters of parameter starting at the character specified by offset. If length is omitted, expands to the substring of parameter start? ing at the character specified by offset. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below). If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter. Arithmetic expressions starting with a - must be separated by whitespace from the preceding : to be distinguished from the Use Default Values expansion. If length evaluates to a number less than zero, and parameter is not @ and not an indexed or associative array, it is interpreted as an offset from the end of the value of parameter rather than a number of characters, and the expan? sion is the characters between the two offsets. If parameter is @, the result is length positional parameters beginning at off? set. If parameter is an indexed array name subscripted by @ or *, the result is the length members of the array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the maximum index of the specified array. Sub? string expansion applied to an associative array produces unde? fined results. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. If offset is 0, and the positional parameters are used, $0 is prefixed to the list.
Answer by user1338062 for Extract substring in bash
I'm surprised this pure bash solution didn't come up:
a="someletters_12345_moreleters.ext" IFS="_" set $a echo $2 # prints 12345
You probably want to reset IFS to what value it was before, or unset IFS
afterwards!
Answer by diyism for Extract substring in bash
similar to substr('abcdefg', 2-1, 3) in php:
echo 'abcdefg'|tail -c +2|head -c 3
Answer by fedorqui for Extract substring in bash
Following the requirements
I have a filename with x number of characters then a five digit sequence surrounded by a single underscore on either side then another set of x number of characters. I want to take the 5 digit number and put that into a variable.
I found some grep
ways that may be useful:
$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]+" 12345
or better
$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]{5}" 12345
And then with -Po
syntax:
$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d+' 12345
Or if you want to make it fit exactly 5 characters:
$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d{5}' 12345
Finally, to make it be stored in a variable it is just need to use the var=$(command)
syntax.
Answer by russell for Extract substring in bash
A little late, but I just ran across this problem and found the following:
host:/tmp$ asd=someletters_12345_moreleters.ext host:/tmp$ echo `expr $asd : '.*_\(.*\)_'` 12345 host:/tmp$
I used it to get millisecond resolution on an embedded system that does not have %N for date:
set `grep "now at" /proc/timer_list` nano=$3 fraction=`expr $nano : '.*\(...\)......'` $debug nano is $nano, fraction is $fraction
Answer by BinaryZebra for Extract substring in bash
If we focus in the concept of:
"A run of (one or several) digits"
We could use several external tools to extract the numbers.
We could quite easily erase all other characters, either sed or tr:
name='someletters_12345_moreleters.ext' echo $name | sed 's/[^0-9]*//g' # 12345 echo $name | tr -c -d 0-9 # 12345
But if $name contains several runs of numbers, the above will fail:
If "name=someletters_12345_moreleters_323_end.ext", then:
echo $name | sed 's/[^0-9]*//g' # 12345323 echo $name | tr -c -d 0-9 # 12345323
We need to use regular expresions (regex).
To select only the first run (12345 not 323) in sed and perl:
echo $name | sed 's/[^0-9]*\([0-9]\{1,\}\).*$/\1/' perl -e 'my $name='$name';my ($num)=$name=~/(\d+)/;print "$num\n";'
But we could as well do it directly in bash(1) :
regex=[^0-9]*([0-9]{1,}).*$; \ [[ $name =~ $regex ]] && echo ${BASH_REMATCH[1]}
This allows us to extract the FIRST run of digits of any length
surrounded by any other text/characters.
Note: regex=[^0-9]*([0-9]{5,5}).*$;
will match only exactly 5 digit runs. :-)
(1): faster than calling an external tool for each short texts. Not faster than doing all processing inside sed or awk for large files.
Answer by morbeo for Extract substring in bash
Ok, here goes pure Parameter Substitution with an empty string. Caveat is that I have defined someletters and moreletters as only characters. If they are alphanumeric, this will not work as it is.
filename=someletters_12345_moreletters.ext substring=${filename//@(+([a-z])_|_+([a-z]).*)} echo $substring 12345
Answer by BinaryZebra for Extract substring in bash
A bash solution:
IFS="_" read -r x digs x <<<'someletters_12345_moreleters.ext'
This will clobber a variable called x
. The var x
could be changed to the var _
.
input='someletters_12345_moreleters.ext' IFS="_" read -r _ digs _ <<<"$input"
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment