In a folder I have several files with the following name-structure (I write just three examples):
F_001_4837_blabla1.doc
F_045_8987_blabla2.doc
F_168_9092_blabla3.doc
What I would do is to use a BASH command to rename all the files in my folder by deleting the first underscore and the series of zeros before the first number code obtaining:
F1_4837_blabla1.doc
F45_8987_blabla2.doc
F168_9092_blabla3.doc
shopt -s extglob
for f in *; do
echo "$f: ${f/_*(0)/}"
# mv "$f" "${f/_*(0)/}" # for the actual rename
done
output
F_001_4837_blabla1.doc: F1_4837_blabla1.doc
F_045_8987_blabla2.doc: F45_8987_blabla2.doc
F_168_9092_blabla3.doc: F168_9092_blabla3.doc
Parameter Expansion
Parameter expansion can be used to replace the content of a variable. In this case, we replace the pattern _*(0) with nothing.
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pat-
tern just as in pathname expansion. Parameter is expanded and
the longest match of pattern against its value is replaced with
string. If pattern begins with /, all matches of pattern are
replaced with string. Normally only the first match is
replaced. If pattern begins with #, it must match at the begin-
ning of the expanded value of parameter. If pattern begins with
%, it must match at the end of the expanded value of parameter.
If string is null, matches of pattern are deleted and the / fol-
lowing pattern may be omitted. If parameter is # or *, the sub-
stitution operation is applied to each positional parameter in
turn, and the expansion is the resultant list. If parameter is
an array variable subscripted with # or *, the substitution
operation is applied to each member of the array in turn, and
the expansion is the resultant list.
Extended pattern matching
Extended pattern matching allows us to use the pattern *(0) to match zero or more 0 characters. It needs to be enabled using the extglob setting.
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol-
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
#(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Related
I can't see to get it working :
echo $VERSIONNUMBER
i get : v0.9.3-beta
VERSIONNUMBERNAME=${VERSIONNUMBER:1}
echo $VERSIONNUMBERNAME
I get : 0.9.3-beta
VERSION=${VERSIONNUMBERNAME/./_}
echo $VERSION
I get : 0_9.3-beta
I want to have : 0_9_3-beta
I've been googling my brains out I can't make heads or tails of it.
Ideally I'd like to remove the v and replace the periods with underscores in one line.
Let's create your variables:
$ VERSIONNUMBER=v0.9.3-beta
$ VERSIONNUMBERNAME=${VERSIONNUMBER:1}
This form only replaces the first occurrence of .:
$ echo "${VERSIONNUMBERNAME/./_}"
0_9.3-beta
To replace all occurrences of ., use:
$ echo "${VERSIONNUMBERNAME//./_}"
0_9_3-beta
Because this approach avoids the creation of pipelines and subshells and the use of external executables, this approach is efficient. This approach is also unicode-safe.
Documentation
From man bash:
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pattern
just as in pathname expansion. Parameter is expanded and the longest
match of pattern against its value is replaced with
string. If pattern begins with /, all matches of pattern are replaced
with string. Normally only the first match is replaced. If
pattern begins with #, it must match at the beginning of the expanded
value of parameter. If pattern begins with %, it must match at the
end of the expanded value of parameter. If string
is null, matches of pattern are deleted and the / following pattern
may be omitted. If the nocasematch shell option is enabled, the
match is performed without regard to the case of alphabetic
characters. If parameter is # or *, the substitution operation is
applied to each positional parameter in turn, and the
expansion is the resultant list. If parameter is an array variable
subscripted with # or *, the substitution operation is
applied to each member of the array in turn, and the expansion is the
resultant list.
(Emphasis added.)
You can combine pattern substitution with tr:
VERSION=$( echo ${VERSIONNUMBER:1} | tr '.' '_' )
I am attempting to write a bash script (poorly) and need assistance in stripping characters from a variable.
variable is defined as $managementipmask= 111.111.111.111/24
I need to strip the /24 from the end of the variable.
Thanks in advance.
Use parameter expansion to remove everything from the first /:
$ k="111.111.111.111/24"
$ echo "${k%%/*}"
111.111.111.111
See this resource on parameter expansion for additional details:
http://mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion
${parameter%pattern}
The 'pattern' is matched against the end of 'parameter'. The result is
the expanded value of 'parameter' with the shortest match deleted.
${parameter%%pattern}
As above, but the longest match is deleted.
So you can delete from the last / using a single %:
$ k="111.111.111.111/24/23"
$ echo "${k%/*}"
111.111.111.111/24
Another way:
k="111.111.111.111/24"
echo "${k/%\/24/}"
It replaces last /24 with empty string.
From Bash Manual:
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern
against its value is replaced with string. If pattern begins with ‘/’,
all matches of pattern are replaced with string. Normally only the
first match is replaced. If pattern begins with ‘#’, it must match at
the beginning of the expanded value of parameter. If pattern begins
with ‘%’, it must match at the end of the expanded value of parameter.
If string is null, matches of pattern are deleted and the / following
pattern may be omitted. If parameter is ‘#’ or ‘’, the substitution
operation is applied to each positional parameter in turn, and the
expansion is the resultant list. If parameter is an array variable
subscripted with ‘#’ or ‘’, the substitution operation is applied to
each member of the array in turn, and the expansion is the resultant
list.
I am wrinting a sed invocation using a shell variable. The variable contains a path name with file name:
sed "file name is '$variable'"
...
variable=/path/path/file.txt
The problem is that I don't need the /path/path/ part. I need just file.txt part in output.
Also my path is dynamic so I am guessing that I need to search (somehow) in a string for a first slash from the ending. How do I do that?
You can use basename to do that:
basename /tmp/a.jpg
a.jpg
You can use the shell's variable substitution feature to remove parts matching a glob pattern:
$ variable=/path/path/file.txt
$ echo ${variable##*/} # Remove longest left part matching "*/"
file.txt
From the bash manual:
${parameter#word}
${parameter##word}
The word is expanded to produce a pattern just as in pathname expansion. If
the pattern matches the beginning of the value of parameter, then the result
of the expansion is the expanded value of parameter with the shortest match-
ing pattern (the ‘‘#’’ case) or the longest matching pattern (the ‘‘##’’
case) deleted. If parameter is # or *, the pattern removal operation is
applied to each positional parameter in turn, and the expansion is the
resultant list. If parameter is an array variable subscripted with # or *,
the pattern removal operation is applied to each member of the array in
turn, and the expansion is the resultant list.
${parameter%word}
${parameter%%word}
The word is expanded to produce a pattern just as in pathname expansion. If
the pattern matches a trailing portion of the expanded value of parameter,
then the result of the expansion is the expanded value of parameter with the
shortest matching pattern (the ‘‘%’’ case) or the longest matching pattern
(the ‘‘%%’’ case) deleted. If parameter is # or *, the pattern removal
operation is applied to each positional parameter in turn, and the expansion
is the resultant list. If parameter is an array variable subscripted with #
or *, the pattern removal operation is applied to each member of the array
in turn, and the expansion is the resultant list.
This question already has answers here:
Syntax with pound and percent sign after shell parameter name [duplicate]
(2 answers)
Closed 3 years ago.
Here is an example to get different parts of a filename
bash-3.2$ pathandfile=/tmp/ff.txt
bash-3.2$ filename=$(basename $pathandfile)
bash-3.2$ echo $filename
ff.txt
bash-3.2$ echo ${filename##*.}
txt
bash-3.2$ echo ${filename%.*}
ff
I was wondering what does ## and % mean in the patterns. How is the patten matching working?
Thanks and regards!
The manpage for bash says:
${parameter#word}
${parameter##word}
Remove matching prefix pattern. The word is expanded to produce a pattern just as
in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the
shortest matching pattern (the # case) or the longest matching pattern (the
## case) deleted. If parameter is # or *, the pattern removal operation is
applied to each positional parameter in turn, and the expansion is the resultant
list. If parameter is an array variable subscripted with # or *, the pattern
removal operation is applied to each member of the array in turn, and the expansion
is the resultant list.
${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to produce a pattern just as
in pathname expansion. If the pattern matches a trailing portion of the expanded
value of parameter, then the result of the expansion is the expanded value of
parameter with the shortest matching pattern (the % case) or the longest matching pattern (the %% case) deleted. If parameter is # or *, the pattern removal
operation is applied to each positional parameter in turn, and the expansion is the
resultant list. If parameter is an array variable subscripted with # or *, the
pattern removal operation is applied to each member of the array in turn, and the
expansion is the resultant list.
From http://tldp.org/LDP/abs/html/string-manipulation.html:
${string##substring}
Deletes longest match of $substring from front of $string.
and
${string%substring}
Deletes shortest match of $substring from back of $string.
See http://tldp.org/LDP/abs/html/string-manipulation.html.
${string##substring}
Deletes longest match of $substring from front of $string.
${string%substring}
Deletes shortest match of $substring from back of $string.
I am a shell script newbie. I want to know the difference between
${var%pattern}
and
${var%%pattern}
Thanks
From man bash:
${parameter%word}
${parameter%%word}
The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the "%" case) or the longest matching pattern (the "%%" case) deleted.
Here's an example of what the difference is:
$ VAR=abcdefabcdef
$ echo ${VAR%def*}
abcdefabc
$ echo ${VAR%%def*}
abc
Notice that there are two possible matches for def* at the end of $VAR: both "defabcdef" and just "def" match. With the "%" the shortest possible match for the pattern def* is deleted, so the trailing "def" is removed. With the "%%" the longest possible match is deleted, so "defabcdef" bites the dust.
From man bash:
${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to
produce a pattern just as in pathname
expansion. If the pattern
matches a trailing portion of the expanded value of
parameter, then the result of the
expansion is the expanded value of
parameter with the shortest matching pattern (the %''
case) or the longest matching pattern
(the%%'' case) deleted.
If parameter is # or *, the pattern removal operation is
applied to each positional parameter
in turn, and the expansion is
the resultant list. If parameter is an array variable
subscripted with # or *, the pattern
removal operation is applied to
each member of the array in turn, and the expansion is the
resultant list.