-1

I have a string say, test_var=ab_c_de_fg_.txt. I need to store ab_c in one variable (characters before the 2nd _) and de_fg_ in a second variable (characters after the second _ and before .txt), so these two variables can be used in further operations.

test_var=ab_c_de_fg_.txt

for ((i=0;i<{#test_var};i++)) do a[$i]="${var:$i:1}" done

flag=0 temp=0

while [["$temp" -le "${#test_var}"]] do if a[temp] -eq "_" && flag -eq 0 flag = 1 continue fi

if a[temp] -eq "_" && flag -eq 1 #var1=arr[0] to arr[$(temp-1)] #var2=arr[$(temp+1)] to arr[#(test_var)] fi

temp=$((temp+1)) done

Please guide me, since I am new to shell scripting. Thanks.

terdon
  • 242,166
  • 1
    You mention an array, but there is no array here. And your code is full of errors, don't you get error messages when you try to run this? What is that script supposed to be doing? It doesn't seem to have any relation to what you describe in your question. – terdon Jun 29 '20 at 09:14
  • 1
    You already got some ready-made answers, but if you want to get that script or any other into even a remotely working condition, I'd suggest starting small, building it in pieces, and testing each piece before proceeding. Some useful that immediately came to mind: https://www.shellcheck.net/ and https://unix.stackexchange.com/questions/134472/brackets-in-if-condition-why-am-i-getting-syntax-errors-without-whitespace/134476 Also, fix the indentation. Having it messed up makes it really hard to read what the script is doing. – ilkkachu Jun 29 '20 at 09:27
  • @terdon, the first loop would create an array made of the individual characters of the variable (if the missing $ was added before {#test_var}) – Stéphane Chazelas Jun 29 '20 at 09:29
  • @terdon, ... and there's the general idea of processing the string character-by-character, checking for the _ separator etc. Looks a bit like what someone might write in C to do that. – ilkkachu Jun 29 '20 at 09:31
  • @StéphaneChazelas yes, but as you say, the individual characters so not what the OP seems to want. – terdon Jun 29 '20 at 09:50
  • @terdon, it looks like they're trying to disassemble the string into an array of individual letters, then loop over that, one item at a time, looking for the separator etc. And then build the final variables from parts of that array. It's a doing it on a lower level than is at all necessary, and full of typos and errors, but the idea is there. – ilkkachu Jun 29 '20 at 11:24

2 Answers2

2

To split a string into an array, you can use the split+glob operator (invoked when you leave a parameter expansion unquoted in list context):

test_var=ab_c_de_fg_.txt
root_name=${test_var%.*} # remove extension

IFS=_ # split on _ set -o noglob # disable glob part array=( $root_name"" ) # split+glob, preserve empty trailing element if any

typeset -p array would then show something like:

typeset -a array=(ab c de fg '')

To join elements of an array with the first character (byte in ksh) of $IFS, you do "${array[*]}".

So:

printf '%s\n' "${array[*]:0:2}" "${array[*]:2}"

Would output:

ab_c
de_fg_

And your two variables could be defined like:

first_part="${array[*]:0:2}" second_part="${array[*]:2}"
1

Here's one way to do what your question asks for in bash (and ignoring your code, since I can't understand what you're trying to do with it):

$ test_var=ab_c_de_fg_.txt
$ read var1 var2 < <(echo "$test_var" | sed 's/_/ /2; s/\.txt$//')
$ echo "$var1"
ab_c
$ echo "$var2"
de_fg_

In a script, that would just be:

test_var=ab_c_de_fg_.txt
read var1 var2 < <(echo "$test_var" | sed 's/_/ /2; s/\.txt$//')

And you now have $var1 and $var2.

The trick is using read to read the two variables. That will split its input on the current value of the environment variable IFS (which, by default, is a space a tab and a newline). The sed command will replace the 2nd _ with a space (s/_/ /2) and remove the .txt from the end of its input (s/\.txt$//), so what is passed to read will be ab_c de_fg_.txt, and because there is a space in the middle, each string is saved in in the corresponding variable.

terdon
  • 242,166
  • Note that it assumes $test_var doesn't contain backslashes, SPC, TAB, newline characters and depending on the echo flavour is not something like -n, -Een... – Stéphane Chazelas Jun 29 '20 at 09:26