You reference parameters and variables with the dollar sign, so the loop counter i can be used as $i within the loop (within double quotes, not single quotes). Then you just need the do and done keywords to start and end the loopy part.
So, the straightforward conversion:
> final_output.txt
for (( i = 1 ; i < 23 ; i += 1)); do
grep -w "^sample$i" "file$i.txt" > "sample${i}_file.txt"
cat "sample${i}_file.txt" >> final_output.txt
done
Using the quotes around "file${i}.txt" is not strictly necessary as long as i only contains a number, but it's a good habit to quote any variable references, for lots of reasons.
Note that in the case of sample${i}_file.txt we need the braces in ${i}, since the underscore is valid in a variable name, and writing $i_file.txt would refer to the variable i_file.
The initial > final_output.txt is to clear the file at first, since we append to it within the loop. Of course, you can just skip creating the sample1_file.txt files if you don't need them, and just grep ... >> final_output.txt.
Alternatively, you could use brace expansion to generate a list of the numbers, instead of counting manually with the for (( ... )) loop, i.e. for i in {1..22}; do ... done.
Or, in standard POSIX shell:
i=1
while [ "$i" -lt 23 ] ; do
grep ...
i=$((i + 1))
done
FOO="^sample1|^sample2|..."and thengrep -e ""$FOO"" > final_output.txt. Not tested, though.