Você pode tentar usar cat para fazer isso, ou seja,
cat < < EOF > output-filename
# $ file_name
#
# Criado por $ MASTER em $ M / $ D / $ Y em $ h: $ m: $ s
# Copyright (c) $ Y $ MASTER. Todos os direitos reservados.
#
EOF
Se você quiser recuar o código acima, altere < < para < < - que removerá as guias principais.
Além disso, sim, é regex ruim. classes de caracteres (colchetes) não precisam de tubos, isto é, para ter combinações alternativas dentro de colchetes. você quer algo como:
Substitua: $ file_name = ~ ^ [0-9 | a-z | A-Z | -] . [Ml]
Com: $ file_name = ~ ^ [0-9a-zA-Z + _-] . [Ml]
Você também pode substituir o * por um + para indicar 1 ou mais, pois esse regex também corresponderia a '.ml'. Certifique-se de que um hífen é o último caractere em uma classe de caracteres, caso contrário, você assumirá que está especificando um intervalo.
EDIT: tente isso, apenas testado com um arquivo .sh, .cpp e .ml. Por curiosidade, é a terceira declaração se for para .ml, ou .m ou .l como você parecia estar combinando? a segunda instrução if também corresponde a .m, portanto, um deles provavelmente está errado, o código abaixo assume o terceiro caso deve ser .ml
function touchm(){
date=$(date +'%Y-%m-%d %H:%M:%S')
read Y M D h m s <<< ${date//[-: ]/ }
file_name=$1
if [[ $file_name =~ ^[0-9a-zA-Z+_-]+\.(py|pl|rb|sh)$ ]]; then
echo "\#
# $file_name
#
# Created by $MASTER on $M/$D/$Y at $h:$m:$s
# Copyright (c) $Y $MASTER. All rights reserved.
#
" > $1
elif [[ $file_name =~ ^[0-9a-zA-Z+_-]+\.(m|h|c|cpp)$ ]]; then
echo "//
// $file_name
//
// Created by $MASTER on $M/$D/$Y at $h:$m:$s
// Copyright (c) $Y $MASTER. All rights reserved.
//
" > $1
elif [[ $file_name =~ ^[0-9a-zA-Z+_-]+\.ml$ ]]; then
echo "(* *)
(* $file_name *)
(* *)
(* Created by $MASTER on $M/$D/$Y at $h:$m:$s *)
(* Copyright (c) $Y $MASTER. All rights reserved. *)
(* *)
" > $1
else
echo "What bullshit. Give me a good file name"
fi
}