Skip to content

Instantly share code, notes, and snippets.

@thingsiplay
Last active June 14, 2025 07:05
Show Gist options
  • Save thingsiplay/889cb2899f35405e10839112f5181ab3 to your computer and use it in GitHub Desktop.
Save thingsiplay/889cb2899f35405e10839112f5181ab3 to your computer and use it in GitHub Desktop.
toarchive - Create one archive for each file or folder (Bash using 7z)
#!/usr/bin/env bash
supported_ext=("7z" "zip")
help() {
cat <<EOF
toarchive ext [options] files...
toarchive zip -f -k *.smc
Convert each file to an archive using 7z or tar, similar to gzip.
options:
ext archive extension and format to create, supported: ${supported_ext[*]}
-r remove original input file on success
-R delete original input files and directory recursively on success
-f force create and overwrite existing archive
-1..9 set compression level, 1=fastest, 9=highest
Careful: Option -R will make use of system command 'rm -r'.
The rest of the options starting with a "-" will be directly forwarded to 7z.
EOF
}
# Create one archive for each file or folder.
if [[ "${#}" -eq 0 ]]; then
help
elif [[ "${1}" == 'help' ]] || [[ "${1}" == '--help' ]] || [[ "${1}" == '-h' ]]; then
help
else
ext=''
for se in "${supported_ext[@]}"; do
if [[ "${se}" == "${1}" ]]; then
ext="${1}"
shift
break
fi
done
if [[ "${ext}" == '' ]]; then
echo "'${1}' is not in list of supported formats: ${supported_ext[*]}"
exit 1
fi
opt=()
stop_parse=false
force_write=false
delete_files=false
recursive_delete_dirs=false
for arg in "${@}"; do
if ! [[ "${stop_parse}" == true ]]; then
if [[ "${arg}" == "--" ]]; then
stop_parse=true
opt+=(--)
continue
elif [[ "${arg}" == '-r' ]]; then
delete_files=true
continue
elif [[ "${arg}" == '-R' ]]; then
recursive_delete_dirs=true
continue
elif [[ "${arg}" == '-f' ]]; then
force_write=true
continue
elif [[ "${arg}" =~ -[1-9] ]]; then
echo "compression level: ${arg}"
compression_level="${arg/-/}"
continue
elif [[ "${arg}" =~ ^- ]]; then
opt+=("${arg}")
continue
fi
fi
if ! [[ "${compression_level}" == "" ]]; then
opt+=("-mx${compression_level}")
fi
if [[ "${arg}" == '' ]]; then
echo "Input path cannot be empty."
exit 1
fi
input_file="$(readlink --canonicalize --quiet "${arg}")"
if ! [[ -e "${input_file}" ]]; then
echo "Input path must point to an existing file or directory: '${input_file}'"
exit 1
fi
output_file="${input_file}.${ext}"
if [[ "${force_write}" == true ]] || ! [[ -f "${output_file}" ]]; then
7z a "${opt[@]}" "${output_file}" "${input_file}"
if [[ "${recursive_delete_dirs}" == true ]] &&
[[ -f "${output_file}" ]]; then
rm --recursive --dir -- "${input_file}"
elif [[ "${delete_files}" == true ]] &&
[[ -f "${output_file}" ]] &&
[[ -f "${input_file}" ]]; then
rm -- "${input_file}"
fi
fi
done
fi
#!/usr/bin/env bash
# Create one archive for each file or folder.
if [ "${#}" -eq -1 ]; then
echo "toarchive ext files..."
echo "toarchive zip *.smc"
else
ext="${1}"
shift
opt=()
stop_parse=false
for arg in "${@}"; do
if [ ! "${stop_parse}" == true ]; then
if [ "${arg}" == "--" ]; then
stop_parse=true
opt+=(--)
continue
elif [[ "${arg}" =~ ^- ]]; then
opt+=("${arg}")
continue
fi
fi
file="${arg}"
7z a "${opt[@]}" "${file}.${ext}" "${file}"
done
fi
@thingsiplay
Copy link
Author

I have added a new version of the script. The old one is renamed to 'toarchive-old'.

The new script has some guard rails and more checks. Also original files can be removed automatically on success, like gzip does. But an option -r must be explicitly given here, like toarchive zip -r file.txt. Directories can be removed too, but the option uppercase -R is required here, as in toarchive zip -R my_dir. Have in mind this will use rm -r system command. Although some guard rails are in place to prevent massive fail, you should be very careful. Note that no file is removed, if -r or -R are not used at all.

@thingsiplay
Copy link
Author

In the extended long new version, all [ .. ] are replaced with the Bash variants [[ .. ]]. And new option for compression level included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment