der Stern[*] wird immer durch eine Zeichenkette ersetzt, der übereinstimmt. *.txt liefert dir also korrekt einen String mit allen Datein mit dem Namen IRGENDWAS.txt und legt pro durchgang einen Dateinamen in $i ab. Jedoch wird der Inhalt von * nicht gespeichert (und selbst wenn, würde das ganze aus einem String aller Datein bestehen, die mit .txt enden und nicht nur der einen Datei von dem Durchgang), somit wird dann bei deinem Umbennenungsversuch bei *.TXT, nicht der Präfix von *.txt zurückgegeben, sondern ein String mit allen Datein, die IRGENDWAS.TXT heißen. Somit versuchst du so ca. soetwas: "cp DATEI.txt datei1.TXT datei2.TXT datei3.TXT dateiN.TXT . cp hat aber die Angewohnheit, bei mehr als 2 Parametern, alle Datein in das Verzeichnis (was im letzten Parameter angegeben ist) zu kopieren, was ja nicht dein Ziel ist

.
Um den Suffix zu verändern, würde ich dir sed empfehlen, was auf jedem Unix dabei sein sollte. Dazu musst du nur die vorletzte Zeile anpassen.
hier die Lösung, wenn du zu "faul" bist selbst zu tüfteln...
Code:
#!/bin/sh
for i in $1/*.txt
do cp "$i" `echo "$i" | sed 's/\.txt$/.TXT/g'`
done
Diese nach links geneigten Anführungszeichen übergeben die Ausgabe (stdout) als Parameter. Also die Ausgabe die die Befehle innerhalb von `` liefern, werden an dieser Stelle als Parameter eingesetzt.
echo "$i" übergibt (dank Pipe ( | )) den Aktuellen Dateinamen an die Eingabe (stdin) von sed, dieser sucht und ersetzt (s) den regulärer Ausdruck (also .txt, jedoch muss es am Ende ($) stehen) durch die Zeichenfolge ".TXT".
Dadurch wird also an cp, als zweiten Parameter, der Inhalt von $i eingetragen, mit dem Unterschied, dass .txt durch .TXT ersetzt worden ist.
Wenn du jetzt noch " \.txt$ " durch " '$var1' " und " .TXT " durch " '$var2' " ersetzt, bist du so gut wie fertig
