Read integers from text file and write to CSV file
Brave attempt :-) This can be so much better ;-)

Running scripts

The script has the shebang #!/bin/bash, but you invoke it as sh script.sh.
The purpose of a shebang is to make scripts runnable as ./script.sh.
When invoked this way, the shell looks at the shebang, and runs the script with the specified executable.
sh is often symlinked to Bash, but not always.

In short, if a script doesn't require Bash, then use the shebang line #!/bin/sh and run it as ./script.sh or sh ./script.sh.
If it requires Bash, then use the shebang line #!/usr/bin/env bash and run it with ./script.sh or bash ./script.sh.

Filtering lines

Bash is not particularly well-suited to filter lines by patterns.
grep is a great tool for that.
So instead of reading line by line with Bash to filter,
look for ways to use grep.
In this example, replace the loop with:

grep '[0-9]$' "$file" | while IFS= read line; do
    ...
done


Empty conditional branches

I think your intention here was to do nothing when the condition is true:


if [ "$lastchar" == : ]     
    then
        echo -ne
elif ...



If you ever need to do nothing, you can use true or : like this:

if ...; then
    :
elif ...


But this is not a good example to use this trick,
because a better solution exists.
A better solution would have been to drop the if, and change the elif to if.
An even better solution would have been to call continue if the line doesn't match the required pattern, so the loop body would be flatter:

if ! [ "$lastchar" -ge 0 -a "$lastchar" -le 9 ]; then
    continue
fi

breakdown=...


With my tip with grep in the previous point, you don't need a condition at all.

Extracting two numbers

This is very inefficient:


breakdown=$(echo "$line" | cut -d':' -f2,6)
master=$(echo "$breakdown" | cut -d'a' -f1)
clone=$(echo "$breakdown" | cut -d':' -f2)
final=$(echo -e "$master,$clone" | tr -d ' ' &gt;&gt; tempsplit.txt)



The problem is that for each line this runs many processes: echo, cut, tr, and multiple $(...) sub-shells.

I see a simpler way to achieve what you want. Looking at these sample lines:


tape with barcode: 000053 and is: offline at listed location: MCR Shelves and is: Full and is copy of tape with barcode: 000047
tape with barcode: 000044 and is: offline at listed location: MCR Shelves and is: Full and is copy of tape with barcode: 000042



We could extract the two numbers and put a comma in between like this:


Replace all non-digits at the beginning with empty string (= remove)
Replace all non-digits with a comma


Try this simple pipeline:

grep '[0-9]$' file | head | sed -e 's/^[^0-9]*//' -e 's/[^0-9][^0-9]*/,/'


This works for the head of the file, but not the entire file. On closer look, there are lines that have a third number between the target numbers, which breaks the above pattern:


  tape with barcode: 000484 and is: online at listed location: i40 QUANTUM and is: Appendable and is copy of tape with barcode: 000483


After replacement this line becomes:


  000484 and is: online at listed location: i40 QUANTUM and is: Appendable and is copy of tape with barcode: 000483


Observe that there is a space after the first number and before the last. So to handle such case, we could change the logic of the second step to: "replace everything between two spaces with a comma".

Let's give that a try, on lines containing "i40":

grep 'i40.*[0-9]$' file | head | sed -e 's/^[^0-9]*//' -e 's/ .* /,/'


It seems the script could be replaced with:

grep '[0-9]$' "$file" | \
    sed -e 's/^[^0-9]*//' -e 's/ .* /,/' | \
    awk 'NR % 2 == 0' | sort -n &gt; tapelist_split.csv


No temporary files needed.

If you have the GNU version of sed (typically in Linux), then you can use it delete every 2nd line instead of awk, slightly simpler:

grep '[0-9]$' "$file" | \
    sed -e 's/^[^0-9]*//' -e 's/ .* /,/' -e '1~2d' | \
    sort -n &gt; tapelist_split.csv


Quoting

When you use variables as command parameters,
it's important to double-quote them to protect from word splitting and globbing. So a loop should read from $file like this:

while ...; do ...; done &lt; "$file"


Understanding command parameters

Why did you use the -rf flags here?


rm -rf tempsplit.txt



There's no good reason to use those flags in the above script.


The -r flag is to delete directories recursively. But the parameter above is a single file. The -r flag serves no purpose.
The -f flag is to force deleting a file that might be protected, or to suppress error in case the file doesn't exist. Neither is the case here. The flag serves no purpose.


Flags in a script that serve no purpose or noise, confusing.
Understand all the flags you are using,
and make sure they have a reason to be there.

The field separator

The variable name is incorrect here:


while IFs= read line



Should have been:

while IFS= read line


Variable names in Bash are case sensitive.