Issue
I have multiple folders and I'm trying to save each folder name as a varible for downstream use in a loop:
for f in TINKER*;
do
name=$(echo $f | sed 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER_$1_$2/')
echo $name
done
Folder examples:
TINKER_more05_less23
TINKER_more55_less218
TINKER_more23_less03
In the case of the first folder above, I want echo $name to output: TINKER_05_23
For some reason, I have been getting empty output from echo $name.
Can anyone help? Thanks
Solution
The +
in POSIX BRE regex matches a literal +
char. You need to add an -E
option to make sed
use the POSIX ERE syntax.
Besides, you need to use \n
, not $n
, in the replacement. perl
uses $n
replacement backreference syntax, but sed
uses \n
.
So you need
sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER_\1_\2/'
When testing with the above data,
fldrs="TINKER_more05_less23 TINKER_more23_less03 TINKER_more55_less218"
for f in $fldrs; do
name=$(echo "$f" | sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER_\1_\2/');
# OR
# name=$(sed -E 's/TINKER_more([0-9]+)_less([0-9]+)/TINKER_\1_\2/' <<< "$f");
echo "$name"
done
The output is
TINKER_05_23
TINKER_23_03
TINKER_55_218
Additionally, if you want to do it in pure Bash:
rx='TINKER_more([[:digit:]]+)_less([[:digit:]]+)'
for f in TINKER*; do
if [[ "$f" =~ $rx ]]; then
echo "TINKER_${BASH_REMATCH[1]}_${BASH_REMATCH[2]}"
fi
done
See this online demo yielding TINKER_05_23
, TINKER_23_03
and TINKER_55_218
again.
The TINKER_more([[:digit:]]+)_less([[:digit:]]+)
regex contains two capturing groups defined with two pairs of unescaped parentheses, and the
${BASH_REMATCH[1]}
contains the contents of Group 1 and ${BASH_REMATCH[2]}
contains the value in Group 2.
Answered By - Wiktor Stribiżew Answer Checked By - Marie Seifert (WPSolving Admin)