bash : update autocompletes.

This commit is contained in:
Dmitry Voronin 2023-10-30 03:49:10 +03:00
parent 7fe861d541
commit 12d31e883c
18 changed files with 371 additions and 304 deletions

View file

@ -300,10 +300,29 @@ Those are self-written scripts to create archives. They are basically compressed
Command|Description Command|Description
---|--- ---|---
`archive [DIRS]`|Create archive with the best compression (slow). If no args given, archives all files in current directory as separate archives. `archive [FILES]`|Create archive with the best compression (slow). If no args given, archives all files in current directory as separate archives.
`archive_fast [DIRS]`|Like normal `archive` but with minimal compression. `archive_fast [FILES]`|Like normal `archive` but with minimal compression.
`archive_check [DIRS]`|Check specified archives or all archives in current directory. `archive_check [ARCHIVES]`|Check specified archives or all archives in current directory.
`unarchive [DIRS]`|Check specified or all archives and extract if they are correct. `archive_name [ARCHIVES] [NAME]`|Rename specified archive ro specified name or simplify name for specified archive or simplify names for all archives.
`unarchive [ARCHIVES]`|Check specified or all archives and extract if they are correct.
## Autocomplete.
Thos are functions that provide tab-completions.
```bash
_foo()
{
_autocomplete "{foo,bar}"
}
complete -F _foo foo
```
Command|Description
---|---
`_autocomplete <ARGS>`|Provide completion based on provided arguments separated by spaces.
`_autocomplete_first <ARGS>`|Same as `_autocomplete` but works only once for first argument.
`_autocomplete_nested`|Provides nested completions, just like `sudo` does.
## Battery. ## Battery.
@ -333,11 +352,12 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`x [FILE]`|Make file executable. `x <FILE>`|Make file executable.
## Color. ## Color.
### How to use. ### How to use.
Most of the time you want to use it with `echo`. To make `echo` respect colors, you need to use `-e` flag like that: Most of the time you want to use it with `echo`. To make `echo` respect colors, you need to use `-e` flag like that:
```bash ```bash
export color_default="\033[0m" export color_default="\033[0m"
@ -347,6 +367,7 @@ echo -e "${color_red}hello world!${color_default}" # will print "hello world!" i
Don't forget to use `color_default` at the end, or your whole terminal will be red. Don't forget to use `color_default` at the end, or your whole terminal will be red.
### List of colors. ### List of colors.
Please note that colors depend on Terminal Emulator and may vary based on its settings. Please note that colors depend on Terminal Emulator and may vary based on its settings.
|Color|Code| |Color|Code|
@ -378,10 +399,10 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`cp [FROM] [TO]`|Copy files or dirs. Actually, it is an alias for `rsync -ahP`. `cp <FROM> <TO>`|Copy files or dirs. Actually, it is an alias for `rsync -ahP`. Multiple `<FROM>` could be specified.
`cp_merge [FROM] [TO]`|Mirror directories. Same as `rsync --delete`. `cp_merge <FROM> <TO>`|Mirror directories. Same as `rsync --delete`.
`cp_link`|Copy directory by recursively creating hardlinks and directories. `cp_link <FROM> <TO>`|Copy directory by recursively creating hardlinks and directories.
`bcp`|Default `cp` command. `bcp <FROM> <TO>`|Default `cp` command.
## Date. ## Date.
@ -402,16 +423,16 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`df`|Show free disk space (only physical media). `df`|Show free disk space (only physical media).
`du [DIR]`|Show disk usage. `du [FILES]`|Show disk usage.
## Docker. ## Docker.
Command|Description Command|Description
---|--- ---|---
`docker_volumes [CONTAINER]`|Show volumes of a specified container. `docker_volumes <CONTAINER>`|Show volumes of a specified container.
`docker_health`|Show containers that exited with an error code. `docker_health`|Show containers that exited with an error code.
`docker_prune`|Heavy cleanup to free up space. `docker_prune`|Heavy cleanup to free up space.
`docker_ip [CONTAINER]`|Show IP of a specified container. `docker_ip <CONTAINER>`|Show IP of a specified container.
`docker_update`|Update all Docker images. `docker_update`|Update all Docker images.
`dc`|Short for `docker compose`. `dc`|Short for `docker compose`.
`dcu [SERVICE]`|Start a compose service. `dcu [SERVICE]`|Start a compose service.
@ -440,13 +461,13 @@ Variable|Description
Command|Description Command|Description
---|--- ---|---
`ffmpeg_mux_audio [SOUND] [RESULT]`|Mux external audio into one container with video (replaces original audio). Run inside dir with original video. [SOUND] names should be the same for each video. `ffmpeg_mux_audio <SOUND> <RESULT>`|Mux external audio into one container with video (replaces original audio). Run inside dir with original video. <SOUND> names should be the same for each video.
## Files. ## Files.
Command|Description Command|Description
---|--- ---|---
`o [FILE]`|Open file with default GUI app. `o <FILE>`|Open file with default GUI app.
## Fix. ## Fix.
@ -454,7 +475,7 @@ Contains simple fixes for warious issues.
Command|Description Command|Description
---|--- ---|---
`fix_ethernet_speed [SPEED]`|Specify ethernet speed if it failed to set correct speed automatically. [SPEED] can be 10/100/1000 etc. `fix_ethernet_speed <SPEED>`|Specify ethernet speed if it failed to set correct speed automatically. [SPEED] can be 10/100/1000 etc.
`fix_files_sftp`|Make Nautilus forget incorrect password for SFTP connection. `fix_files_sftp`|Make Nautilus forget incorrect password for SFTP connection.
## Git. ## Git.
@ -503,22 +524,22 @@ Command|Description
`name [FILES]`|Replace all non-alphanumeric characters in file with underscores. `name [FILES]`|Replace all non-alphanumeric characters in file with underscores.
`name_hash [FILES]`|Replace all file names with hashes, keep extension. `name_hash [FILES]`|Replace all file names with hashes, keep extension.
`name_hash_check [FILES]`|Check all file hashes. `name_hash_check [FILES]`|Check all file hashes.
`name_series [SEASON]`|Rename files to Jellyfin's show format: `Episode S01E01.mkv`. `name_series <SEASON>`|Rename files to Jellyfin's show format: `Episode S01E01.mkv`.
`name_manga [SEASON]`|Rename files to Kavita's manga format: `Name Vol.1 Ch.01.cbr`. `name_manga <SEASON>`|Rename files to Kavita's manga format: `Name Vol.1 Ch.01.cbr`.
`name_ext [EXTENSION] [FILES]`|Change file extensions. `name_ext <EXTENSION> [FILES]`|Change file extensions.
## Ncdu. ## Ncdu.
Command|Description Command|Description
---|--- ---|---
`ncdu`|Show recursive disk usage. Only on the same filesystem. `ncdu [DIR]`|Show recursive disk usage. Only on the same filesystem.
## Notify. ## Notify.
Command|Description Command|Description
---|--- ---|---
`notify`|Send notification. `notify <MESSAGE>`|Send notification.
`notify_silent`|Send silent notification. `notify_silent <MESSAGE>`|Send silent notification.
## Own. ## Own.
@ -537,12 +558,12 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`ps [PROGRAM]`|Show process info for matching [PROGRAM] name. `ps <PROGRAM>`|Show process info for matching [PROGRAM] name.
## Recursive. ## Recursive.
Command|Description Command|Description
---|--- ---|---
`recursive [COMMAND]`|Cd into every directory recursively and run specified command in each dir. `recursive <COMMAND>`|Cd into every directory recursively and run specified command in each dir.
## Shopt. ## Shopt.
@ -568,12 +589,12 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`ta [NAME]`|Attach to session by name. `ta [NAME]`|Attach to session by name. Default is `main`.
`td`|Detach from session. `td`|Detach from session.
`tl`|List all sessions. `tl`|List all sessions.
`tr`|Rename session. `tr`|Rename session.
`tn`|Name window. `tn`|Name window.
`tk [NAME]`|Kill session. `tk [NAME]`|Kill session. Default is `main`.
`tka`|Kill all sessions. `tka`|Kill all sessions.
## To-do. ## To-do.
@ -586,16 +607,16 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`tb [NAME]`|Attach to box by name. `tb [NAME]`|Attach to box by name. Default is `main`.
`tbk [NAME]`|Kill box by name. `tbk [NAME]`|Kill box by name. Default is `main`.
`tb_rpmfusion [NAME]`|Install RPMFusion package to box by name. `tb_rpmfusion [NAME]`|Install RPMFusion package to box by name. Default is `main`.
`tbl`|List all boxes. `tbl`|List all boxes.
## Try. ## Try.
Command|Description Command|Description
---|--- ---|---
`try`|Repeat the command every 2 seconds until it exits with success. `try <COMMAND>`|Repeat the command every 2 seconds until it exits with success.
## Umask. ## Umask.
@ -605,8 +626,8 @@ By default, umask is `077` which means group and others have no access when file
Command|Description Command|Description
---|--- ---|---
`vdl [LINK]`|Download video/playlist. `vdl <LINK>`|Download video/playlist.
`vdl_file [FILE]`|Download all links from a file. `vdl_file <FILE>`|Download all links from a file.
`vdl_update`|Update playlist that was downloaded with `vdl` before. `vdl_update`|Update playlist that was downloaded with `vdl` before.
`vdl_update_all`|Recursive `vdl_update`. `vdl_update_all`|Recursive `vdl_update`.
@ -620,11 +641,11 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`wallpaper [FILE]`|Set specified file as a wallpaper. `wallpaper <FILE>`|Set specified file as a wallpaper.
## Watch. ## Watch.
Command|Description Command|Description
---|--- ---|---
`w [COMMAND]`|Alias for `watch`. `w <COMMAND>`|Alias for `watch`.
`ww [COMMAND]`|Alias for `watch` that updates every 0.1 seconds. `ww <COMMAND>`|Alias for `watch` that updates every 0.1 seconds.

View file

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
#home="/var/home/voronind" #home="/var/home/voronind"
home="$HOME" home="${HOME}"
module="$home/document/linux/config/bash/module" module="${home}/document/linux/config/bash/module/*.sh"
# src default # src default
if [[ -f /etc/bashrc ]]; then if [[ -f /etc/bashrc ]]; then
@ -10,8 +10,8 @@ if [[ -f /etc/bashrc ]]; then
fi fi
# src custom # src custom
for file in $(ls "$module"); do for file in ${module}; do
source "$module/$file" source "${file}"
done done
# alias to reload # alias to reload

View file

@ -0,0 +1,7 @@
# Help page for scripting.
# Conventions.
## Bash manpage arguments.
`[OPTIONAL] <REQUIRED> {DEFAULT} (INFO)`

View file

@ -1,91 +1,97 @@
# archive file with maximum compression and checksum. # archive file with maximum compression and checksum.
# usage: archive [FILES]
archive() archive()
{ {
local target="$@" # target file(s). local targets=("${@}") # target file(s).
local count=0 # processed count. local count=0 # processed count.
local total=$# # total to process. local total=${#} # total to process.
# set dafult value to target all supported archives. # set dafult value to target all supported archives.
if [[ "${target}" = "" ]]; then if [[ "${targets}" = "" ]]; then
target="*" targets=(*)
total=$(ls | wc -l) total=${#targets[@]}
fi fi
# iterate each file. # iterate each target.
for file in ${target}; do for target in "${targets[@]}"; do
# increment counter. # increment counter.
((count++)) ((count++))
# status info. # status info.
local status="[${count}/${total}] ${file}" local status="[${count}/${total}] ${target}"
echo "${status}" echo "${status}"
# create archive. # create archive.
tar -c "${file}" | pv -s $(du -sb "${file}" | awk '{print $1}') | xz -9e > "${file%/*}".tar.xz tar -c "${target}" | pv -s $(du -sb "${target}" | awk '{print $1}') | xz -9e > "${target%/*}".tar.xz
# append hash to file name. # append hash to target name.
mv "${file%/*}".tar.xz "${file%/*}"_$(sha1sum "${file%/*}".tar.xz | cut -d\ -f1).tar.xz mv "${target%/*}".tar.xz "${target%/*}"_$(sha1sum "${target%/*}".tar.xz | cut -d\ -f1).tar.xz
done done
} }
# archive file with minimal compression and checksum. # archive file with minimal compression and checksum.
# usage: archive_fast [FILES]
archive_fast() archive_fast()
{ {
local target="$@" # target file(s). local targets=("${@}") # target file(s).
local count=0 # processed count. local count=0 # processed count.
local total=$# # total to process. local total=${#} # total to process.
# set dafult value to target all supported archives. # set dafult value to target all supported archives.
if [[ "${target}" = "" ]]; then if [[ "${targets}" = "" ]]; then
target="*" targets=(*)
total=$(ls | wc -l) total=${#targets[@]}
fi fi
# iterate each file. # iterate each target.
for file in ${target}; do for target in "${targets[@]}"; do
# increment counter. # increment counter.
((count++)) ((count++))
# status info. # status info.
local status="[${count}/${total}] ${file}" local status="[${count}/${total}] ${target}"
echo "${status}" echo "${status}"
# create archive. # create archive.
tar -c "${file}" | pv -s $(du -sb "${file}" | awk '{print $1}') | gzip -1 > "${file%/*}".tar.gz tar -c "${target}" | pv -s $(du -sb "${target}" | awk '{print $1}') | gzip -1 > "${target%/*}".tar.gz
# append hash to file name. # append hash to target name.
mv "${file%/*}".tar.gz "${file%/*}"_$(sha1sum "${file%/*}".tar.gz | cut -d\ -f1).tar.gz mv "${target%/*}".tar.gz "${target%/*}"_$(sha1sum "${target%/*}".tar.gz | cut -d\ -f1).tar.gz
done done
} }
# check archive hashes. # check archive hashes.
# usage: archive_check [FILES]
archive_check() archive_check()
{ {
local target="$@" # target file(s). local targets=("${@}") # target file(s).
local count=0 # processed count. local total=${#} # total to process.
local total=$# # total to process. local count=0 # processed count.
local failed=0 # total failed checks. local failed=0 # total failed checks.
# set dafult value to target all supported archives. # set dafult value to target all supported archives.
if [[ "${target}" = "" ]]; then if [[ "${targets}" = "" ]]; then
target="*_*.tar.*" targets=(*_*.tar.*)
total=$(ls ${target} | wc -l) total=${#targets[@]}
fi fi
# iterate each file. # iterate each target.
for file in ${target}; do for target in "${targets[@]}"; do
# process only files.
[[ -f "${target}" ]] || continue
# increment counter. # increment counter.
((count++)) ((count++))
# status info. # status info.
local status="[${count}/${total}] ${file}" local status="[${count}/${total}] ${target}"
# extract hash from name. # extract hash from name.
local saved="${file##*_}" local saved="${target##*_}"
saved="${saved%%.*}" saved="${saved%%.*}"
# calculate actual hash. # calculate actual hash.
local actual="$(pv ${file} | sha1sum | cut -d\ -f1)" local actual=$(pv "${target}" | sha1sum | cut -d\ -f1)
# compare hashes, show error on mismatch. # compare hashes, show error on mismatch.
if [[ "${actual}" = "${saved}" ]]; then if [[ "${actual}" = "${saved}" ]]; then
@ -107,78 +113,102 @@ archive_check()
} }
# extract previously created archive with checksum validation. # extract previously created archive with checksum validation.
# usage: unarchive [FILES]
unarchive() unarchive()
{ {
local target="$@" # target file(s). local targets=("${@}") # target file(s).
local count=0 # processed count. local count=0 # processed count.
local total=$# # total to process. local total=${#} # total to process.
# set dafult value to target all supported archives. # set dafult value to target all supported archives.
if [[ "${target}" = "" ]]; then if [[ "${targets}" = "" ]]; then
target="*_*.tar.*" targets=(*_*.tar.*)
total=$(ls ${target} | wc -l) total=${#targets[@]}
fi fi
# iterate each file. # iterate each target.
for file in ${target}; do for target in "${targets[@]}"; do
# increment counter. # increment counter.
((count++)) ((count++))
# status info. # status info.
local status="[${count}/${total}] ${file}" local status="[${count}/${total}] ${target}"
# extract hash from name. # extract hash from name.
local saved="${file##*_}" local saved="${target##*_}"
saved="${saved%%.*}" saved="${saved%%.*}"
# calculate actual hash. # calculate actual hash.
local actual="$(sha1sum ${file} | cut -d\ -f1)" local actual=$(sha1sum "${target}" | cut -d\ -f1)
# extract if hash matched or show error if not. # extract if hash matched or show error if not.
if [[ "${saved}" = "${actual}" ]]; then if [[ "${saved}" = "${actual}" ]]; then
echo "${status}: OK." echo "${status}: OK."
tar -xf "${file}" tar -xf "${target}"
else else
echo "${status}: failed." echo "${status}: failed."
fi fi
done done
} }
# rename archive. # rename archive. if no name specified, it simplifies archive's name.
# usage: archive_rename [ARCHIVE] [NAME] # usage: archive_name [ARCHIVE] [NAME]
archive_rename() archive_name()
{ {
# get params. local targets="${1}" # target archive(s).
local target="${1}" local name="${2}" # new name.
local name="${2}" local total=1 # total targets to process.
local count=0 # processed targets counter.
# check params. # set dafult value to target all supported archives.
if [[ "${target}" = "" || "${name}" = "" ]]; then if [[ "${targets}" = "" ]]; then
echo "usage: archive_rename [ARCHIVE] [NAME]" targets=(*_*.tar.*)
return 1 total=${#targets[@]}
fi fi
# remove old name. # iterate each target.
local data="${target##*_}" for target in "${targets[@]}"; do
local new_name="${name}_${data}" # only work with targets.
[[ -f "${target}" ]] || continue
# prepare status. # iterate counter.
local status="${target} -> ${new_name}" ((count++))
# rename. # simplify name by default.
mv -- "${target}" "${new_name}" && echo "${status}" || echo -e "${color_red}${status}: error.${color_default}" if [[ "${name}" = "" || ${count} -gt 1 ]]; then
name="${target%_*}"
name="$(parse_alnum ${name})"
fi
# remove old name.
local data="${target##*_}"
local new_name="${name}_${data}"
# prepare status.
local status="[${count}/${total}] ${target} -> ${new_name}"
# check for the same name.
if [[ "${target}" = "${new_name}" ]]; then
echo -e "${color_green}${status}: no change.${color_default}"
continue
fi
# check for existing target.
if [[ -f "${new_name}" ]]; then
echo -e "${color_red}${status}: already exists.${color_default}"
return 1
fi
# rename.
mv -- "${target}" "${new_name}" && echo "${status}" || echo -e "${color_red}${status}: error.${color_default}"
done
} }
# export everything, primarily for use with parallel.. # export everything, primarily for use with parallel..
export -f archive archive_fast archive_check unarchive export -f archive archive_fast archive_check unarchive archive_name
# autocomplete. # autocomplete.
_archive_list() _archive_name()
{
_autocomplete "$(ls *_*.tar.* 2> /dev/null)"
}
_archive_rename()
{ {
COMPREPLY=() COMPREPLY=()
@ -187,7 +217,7 @@ _archive_rename()
local command="${COMP_WORDS[0]}" local command="${COMP_WORDS[0]}"
if [[ "${prev}" = "${command}" ]]; then if [[ "${prev}" = "${command}" ]]; then
COMPREPLY=( $(compgen -W "$(ls -a)" -- ${cur}) ) COMPREPLY=( $(compgen -W "$(ls *_*.tar.*)" -- ${cur}) )
return 0 return 0
else else
local name="${prev%_*}" local name="${prev%_*}"
@ -196,5 +226,5 @@ _archive_rename()
fi fi
} }
complete -o plusdirs -F _archive_list archive_check unarchive complete -f -X "!*_*.tar.*" archive_check unarchive
complete -F _archive_rename archive_rename complete -F _archive_name archive_name

View file

@ -1,9 +1,9 @@
# bash autocomplete. # bash autocomplete.
# usage: _foo () { _autocomplete "{foo,bar}" } ; complete -F _foo foo # usage: _foo() { _autocomplete "{foo,bar}" } ; complete -F _foo foo
# there are also options like -o nospace. see man for more info. # there are also options like -o nospace. see man for more info.
_autocomplete() _autocomplete()
{ {
local commands="$@" local commands="${@}"
COMPREPLY=() COMPREPLY=()
@ -18,7 +18,7 @@ _autocomplete()
# autocomplete only first argument. # autocomplete only first argument.
_autocomplete_first() _autocomplete_first()
{ {
local commands="$@" local commands="${@}"
COMPREPLY=() COMPREPLY=()
@ -32,26 +32,6 @@ _autocomplete_first()
fi fi
} }
# autocomplete only first argument. the rest is ls output.
_autocomplete_first_ls()
{
local commands="$@"
COMPREPLY=()
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local command="${COMP_WORDS[0]}"
if [[ "${prev}" = "${command}" ]]; then
COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
return 0
else
COMPREPLY=( $(compgen -W "$(ls -a)" -- ${cur}) )
return 0
fi
}
# autocomplete nested program. # autocomplete nested program.
_autocomplete_nested() _autocomplete_nested()
{ {
@ -62,7 +42,7 @@ _autocomplete_nested()
if [[ ${words[i]} != -* ]]; then if [[ ${words[i]} != -* ]]; then
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
local root_command=${words[i]} local root_command=${words[i]}
_command_offset $i _command_offset ${i}
return return
fi fi
done done

View file

@ -1,4 +1,6 @@
# create or check checksums for all files in current directory. # create or check checksums for all files in current directory.
# usage: checksum <ACTION>
# actions: "new", "check".
checksum() checksum()
{ {
local action="$1" # what to do with checksum. local action="$1" # what to do with checksum.

View file

@ -1,2 +1,2 @@
alias copy="wl-copy" alias copy="wl-copy" # copy stdin to system clipboard.
alias paste="wl-paste" alias paste="wl-paste" # paste system clipboard to stdout.

View file

@ -1,2 +1,2 @@
alias dconf_load="dconf load / < $HOME/document/linux/config/gnome.dconf" alias dconf_load="dconf load / < $HOME/document/linux/config/gnome.dconf" # load gnome settings.
alias dconf_save="dconf dump / > $HOME/document/linux/config/_gnome.dconf" alias dconf_save="dconf dump / > $HOME/document/linux/config/_gnome.dconf" # dump gnome settings to a file.

View file

@ -8,6 +8,7 @@ alias docker_health="docker ps -a | grep Exited"
alias docker_prune="docker system prune --volumes --all" alias docker_prune="docker system prune --volumes --all"
# short aliases. # short aliases.
# usage: dc [SERVICE]
alias dc="docker compose" alias dc="docker compose"
alias dcu="docker compose up -d" alias dcu="docker compose up -d"
alias dcd="docker compose down" alias dcd="docker compose down"
@ -16,24 +17,31 @@ alias dcl="docker compose logs -f"
alias dcr="docker compose restart" alias dcr="docker compose restart"
alias dcs="docker compose stop" alias dcs="docker compose stop"
# down & up specified services.
# usage: dcdu [SERVICES]
dcdu() dcdu()
{ {
dcd "${@}" dcd "${@}"
dcu "${@}" dcu "${@}"
} }
# pull & up specified services.
# usage: dcpu [SERVICES]
dcpu() dcpu()
{ {
dcp "${@}" dcp "${@}"
dcu "${@}" dcu "${@}"
} }
# up & attach to logs for specified services.
# usage: dcul [SERVICES]
dcul() dcul()
{ {
dcu "${@}" && dcl "${@}" dcu "${@}" && dcl "${@}"
} }
# find out container's IP address. # find out container's IP address.
# usage: docker_up <CONTAINER NAME>
docker_ip() docker_ip()
{ {
docker inspect -f '\''{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'\' $1 | sed "s/^.//" | sed "s/.$//" docker inspect -f '\''{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'\' $1 | sed "s/^.//" | sed "s/.$//"

View file

@ -1,8 +1,9 @@
# mux audio into containers. tmp usage for anime downloads. # mux audio into containers. file names in sound and current dirrectories must match. tmp usage for anime downloads.
# usage: ffmpeg_mux_audio <SOUND> <OUTPUT DIR>
ffmpeg_mux_audio() ffmpeg_mux_audio()
{ {
if [[ "$1" = "" ]]; then if [[ "$1" = "" ]]; then
echo "usage: $ sound/ result/" echo "usage: ffmpeg_mux_audio <SOUND> <OUTPUT DIR>"
return return
fi fi

View file

@ -1,2 +1,3 @@
# open file/dir in GUI. # open file/dir in GUI.
# usage: o <FILE>
alias o="xdg-open" alias o="xdg-open"

View file

@ -1,15 +1,17 @@
# fix when ethernet mistakenly detects 100 Mb instead of 1000 Mb. # fix when ethernet mistakenly detects 100 Mb instead of 1000 Mb.
# usage: fix_ethernet_speed <DEVICE> <SPEED>
# SPEED is one of 10/100/1000 etc.
fix_ethernet_speed() fix_ethernet_speed()
{ {
local device="$1" local device="${1}"
local speed="$2" local speed="${2}"
if [[ "$device" = "" || "$speed" = "" ]]; then if [[ "${device}" = "" || "${speed}" = "" ]]; then
echo "usage: [device] [speed]" echo "usage: fix_ethernet_speed <DEVICE> <SPEED>"
return 1 return 1
fi fi
ethtool -s "$device" speed "$speed" ethtool -s "${device}" speed "${speed}"
} }
# fix files wrong sftp password. # fix files wrong sftp password.

View file

@ -23,14 +23,22 @@ git_tag()
git log | grep commit -m1 | sed -e "s/.*\ //g" | cut -c 1-11; git log | grep commit -m1 | sed -e "s/.*\ //g" | cut -c 1-11;
} }
# alias to preview diff while adding. # alias to preview diff while adding. adds current dir by default.
# usage: ga [FILES]
ga() ga()
{ {
git diff $@ local target=${@}
git add $@
if [[ "${target}" = "" ]]; then
target="."
fi
git diff ${target}
git add ${target}
} }
# rebase by X commits or from root. # rebase by X commits or from root. when COUNT is 0 - rebase from root. default is 2.
# usage: gr [COMMIT COUNT]
gr() gr()
{ {
local base="${1}" local base="${1}"
@ -88,7 +96,7 @@ fi
_gu() _gu()
{ {
_autocomplete account@voronind.com dd.voronin@fsight.ru _autocomplete_first account@voronind.com dd.voronin@fsight.ru
} }
complete -F _gu gu complete -F _gu gu

View file

@ -15,19 +15,20 @@ ll()
} }
# list files in tree structure. # list files in tree structure.
# usage: lll [DEPTH] [FILES]
lll() lll()
{ {
local depth="$1" local depth="${1}"
local paths="${@:2}" local target="${@:2}"
if [[ "$paths" = "" ]]; then if [[ "${target}" = "" ]]; then
paths="." target="."
fi fi
if [[ "$depth" = "" ]]; then if [[ "${depth}" = "" ]]; then
tree -a -- "$paths" tree -a -- "${target}"
else else
tree -a -L "$depth" -- "$paths" tree -a -L "${depth}" -- "${target}"
fi fi
} }

View file

@ -2,49 +2,41 @@
# usage: name [FILES] # usage: name [FILES]
name() name()
{ {
local files="$@" local targets=("${@}") # target file(s).
local count=0 local count=0 # processed count.
local total=$# local total=${#} # total to process.
local IFS=$'\n'
# all files except hidden by default. # all targets except hidden by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls | wc -l) total=${#targets[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# increment count. # increment counter.
((count++)) ((count++))
# extract new name. # parse new name.
local new_name=$(echo "${file}" | \ local new_name=$(parse_simplify "${target}")
sed -e "s/ /_/g" \
-e "s/[^[:alnum:]\._-]//g" \
-e "s/_\+/_/g" -e "s/\.\+/\./g" -e "s/-\+/-/g" \
-e "s/_-/_/g" -e "s/-_/_/g" -e "s/\.-/\./g" -e "s/-\./\./g" -e "s/\._/\./g" -e "s/_\./\./g" \
-e "s/_\+/_/g" \
-e "s/^_//" -e "s/_$//"
)
# status line. # status line.
local status="[${count}/${total}] ${file} -> ${new_name}" local status="[${count}/${total}] ${target} -> ${new_name}"
# check if same name. # check if same name.
if [[ "${file}" = "${new_name}" ]]; then if [[ "${target}" = "${new_name}" ]]; then
echo -e "${color_green}${status}: no change.${color_default}" echo -e "${color_green}${status}: no change.${color_default}"
continue continue
fi fi
# check if file name already exists. # check if target name already exists.
if [[ -f "${new_name}" ]]; then if [[ -f "${new_name}" ]]; then
echo -e "${color_red}${status}: already exists!${color_default}" echo -e "${color_red}${status}: already exists!${color_default}"
return 1 return 1
fi fi
# rename file. # rename target.
mv -- "${file}" "${new_name}" &> /dev/null mv -- "${target}" "${new_name}" &> /dev/null
# show change. # show change.
echo "${status}" echo "${status}"
@ -55,51 +47,50 @@ name()
# usage: name_hash [FILES] # usage: name_hash [FILES]
name_hash() name_hash()
{ {
local files="$@" local targets=("${@}") # target file(s).
local count=0 local count=0 # processed counter.
local total=$# local total=${#} # total to process.
local IFS=$'\n'
# all files except hidden by default. # all targets except hidden by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls -p | grep -v / | wc -l) total=${#targets[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# process only files. # process only targets.
if [[ -f "${file}" ]]; then [[ -f "${target}" ]] || continue
# increment count.
((count++))
# extract extension. # increment count.
local extension="${file##*.}" ((count++))
if [[ "${extension}" = "${file}" ]]; then
extension=""
else
extension=".${extension}"
fi
# hash the new name. # extract extension.
local hash=$(sha1sum -- "${file}" | cut -d\ -f1) local extension="${target##*.}"
new_name="${hash,,}${extension}" if [[ "${extension}" = "${target}" ]]; then
extension=""
# prepare status. else
local status="[${count}/${total}] ${file} -> ${new_name}" extension=".${extension}"
# check if same name.
if [[ "${file}" = "${new_name}" ]]; then
echo -e "${color_green}${status}: no change.${color_default}"
continue
fi
# rename file.
mv -- "${file}" "${new_name}" &> /dev/null
# show change.
echo -e "${status}"
fi fi
# hash the new name.
local hash=$(sha1sum -- "${target}" | cut -d\ -f1)
new_name="${hash,,}${extension}"
# prepare status.
local status="[${count}/${total}] ${target} -> ${new_name}"
# check if same name.
if [[ "${target}" = "${new_name}" ]]; then
echo -e "${color_green}${status}: no change.${color_default}"
continue
fi
# rename target.
mv -- "${target}" "${new_name}" &> /dev/null
# show change.
echo -e "${status}"
done done
} }
@ -107,31 +98,30 @@ name_hash()
# usage: name_hash_check [FILES] # usage: name_hash_check [FILES]
name_hash_check() name_hash_check()
{ {
local files="$@" local targets=("${@}") # target file(s).
local count=0 local total=${#} # total to process.
local total=$# local count=0 # processed counter.
local failed=0 local failed=0 # failed to process counter.
local IFS=$'\n'
# all files by default. # all targets by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls -p | grep -v / | wc -l) total=${#target[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# process only files. # process only targets.
if [[ -f "${file}" ]]; then if [[ -f "${target}" ]]; then
# increment count. # increment count.
((count++)) ((count++))
# status info. # status info.
local status="[${count}/${total}] ${file}" local status="[${count}/${total}] ${target}"
# extract hashes. # extract hashes.
local stored="${file%%.*}" local stored="${target%%.*}"
local actual=$(sha1sum -- "${file}" | cut -d\ -f1) local actual=$(sha1sum -- "${target}" | cut -d\ -f1)
# compare hashes. # compare hashes.
if [[ "${stored}" = "${actual}" ]]; then if [[ "${stored}" = "${actual}" ]]; then
@ -154,127 +144,127 @@ name_hash_check()
} }
# rename files for Jellyfin series, i.e. Episode S01E01.mkv # rename files for Jellyfin series, i.e. Episode S01E01.mkv
# usage: name_series [SEASON] # usage: name_series <SEASON>
name_series() name_series()
{ {
local season="${1}" local season="${1}" # season number.
local files="${@:2}" local targets="${@:2}" # target files.
local count=0 local count=0 # processed counter.
local total=$# local total=${#} # total to process.
local IFS=$'\n'
# error when no season number specified. # error when no season number specified.
if [[ "${season}" = "" ]]; then if [[ "${season}" = "" ]]; then
echo "usage: name_series [SEASON]" echo "usage: name_series <SEASON>"
return 1 return 1
fi fi
# all files by default. # all targets by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls -p | grep -v / | wc -l) total=${#targets[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# process only files. # process only targets.
if [[ -f "${file}" ]]; then if [[ -f "${target}" ]]; then
# increment episode number. # increment episode number.
((count++)) ((count++))
# extract new name. # extract new name.
local new_name="Episode S${season}E$(printf %02d ${count}).${file##*.}" local new_name="Episode S${season}E$(printf %02d ${count}).${target##*.}"
# prepare status. # prepare status.
local status="[${count}/${total}] ${file} -> ${new_name}" local status="[${count}/${total}] ${target} -> ${new_name}"
# rename file. # rename target.
mv -- "${file}" "${new_name}" &> /dev/null mv -- "${target}" "${new_name}" &> /dev/null
echo -e "${status}" echo -e "${status}"
fi fi
done done
} }
# rename files for Kavita manga format. # rename files for Kavita manga format.
# usage: name_manga [SEASON] # usage: name_manga <SEASON>
name_manga() name_manga()
{ {
local season="$1" local season="${1}" # season number.
local files="${@:2}" local targets="${@:2}" # target files.
local count=0 local count=0 # processed counter.
local total=$# local total=${#} # total to process.
local manga="${PWD##*/}" local manga="${PWD##*/}" # manga name.
local IFS=$'\n'
# error when no season number specified. # error when no season number specified.
if [[ "${season}" = "" ]]; then if [[ "${season}" = "" ]]; then
echo "usage: name_manga [SEASON]" echo "usage: name_manga <SEASON>"
return 1 return 1
fi fi
# all files by default. # all targets by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls -p | grep -v / | wc -l) total=${#targets[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# process only files. # process only targets.
if [[ -f "${file}" ]]; then if [[ -f "${target}" ]]; then
# increment episode number. # increment episode number.
((count++)) ((count++))
# extract new name. # extract new name.
local new_name="${manga} Vol.${season} Ch.${count}.${file##*.}" local new_name="${manga} Vol.${season} Ch.${count}.${target##*.}"
# prepare status. # prepare status.
local status="[${count}/${total}] ${file} -> ${new_name}" local status="[${count}/${total}] ${target} -> ${new_name}"
# rename file. # rename target.
mv -- "${file}" "${new_name}" &> /dev/null mv -- "${target}" "${new_name}" &> /dev/null
echo -e "${status}" echo -e "${status}"
fi fi
done done
} }
# rename files for new extension. # rename files for new extension.
# usage: name_ext [EXTENSION] [FILES] # usage: name_ext <EXTENSION> [FILES]
name_ext() name_ext()
{ {
local extension="$1" local extension="${1}" # new extension.
local files="${@:2}" local targets="${@:2}" # target file(s).
local count=0 local count=0 # processed counter.
local total=$# local total=${#} # total to process.
local IFS=$'\n'
# remove extension name from total files.
((total--))
# error when no new extension specified. # error when no new extension specified.
if [[ "${extension}" = "" ]]; then if [[ "${extension}" = "" ]]; then
echo "usage: name_ext [EXTENSION] [FILES]" echo "usage: name_ext <EXTENSION> [targets]"
return 1 return 1
fi fi
# all files by default. # all targets by default.
if [[ "${files}" = "" ]]; then if [[ "${targets}" = "" ]]; then
files="[^.]*" targets=([^.]*)
total=$(ls -p | grep -v / | wc -l) total=${#targets[@]}
fi fi
# process. # process.
for file in ${files}; do for target in "${targets[@]}"; do
# process only files. # process only targets.
if [[ -f "${file}" ]]; then if [[ -f "${target}" ]]; then
# increment count. # increment count.
((count++)) ((count++))
# extract new name. # extract new name.
local new_name="${file%.*}"."${extension}" local new_name="${target%.*}"."${extension}"
# rename file. # rename target.
mv -- "${file}" "${new_name}" &> /dev/null mv -- "${target}" "${new_name}" &> /dev/null
# show change. # show change.
echo "[${count}/${total}] ${file} -> ${new_name}" echo "[${count}/${total}] ${target} -> ${new_name}"
fi fi
done done
} }

View file

@ -1,4 +1,5 @@
# change file ownership to specified user id and restrict access to him. # change file ownership to specified user id and restrict access to him.
# usage: own [USER] [FILES]
own() own()
{ {
local file="${2}" local file="${2}"
@ -20,11 +21,3 @@ own()
# remove access from group and others. # remove access from group and others.
chmod -077 -R "${file}" chmod -077 -R "${file}"
} }
# autocomplete.
_own()
{
_autocomplete_first_ls "{0,1000}"
}
complete -F _own own

View file

@ -0,0 +1,20 @@
# parse data and output simplified format.
# usage: parse_simplify <STRING>
parse_simplify()
{
echo "${*}" | \
sed -e "s/ /_/g" \
-e "s/[^[:alnum:]\._-]//g" \
-e "s/_\+/_/g" -e "s/\.\+/\./g" -e "s/-\+/-/g" \
-e "s/_-/_/g" -e "s/-_/_/g" -e "s/\.-/\./g" -e "s/-\./\./g" -e "s/\._/\./g" -e "s/_\./\./g" \
-e "s/_\+/_/g" \
-e "s/^_//" -e "s/_$//"
}
# parse data keeping only alphanumeric characters.
# usage: parse_alnum <STRING>
parse_alnum()
{
echo "${*}" | \
sed -e "s/[^[:alnum:]]//g"
}

View file

@ -1,11 +1,12 @@
# create toolbx container with default or specified name. # create toolbx container with default or specified name.
# usage: tb [NAME]
tb() tb()
{ {
local name="$1" local name="$1"
# set default name. # set default name.
if [[ "$name" = "" ]]; then if [[ "$name" = "" ]]; then
name="toolbx" name="main"
fi fi
# start container or run command inside it if specified. # start container or run command inside it if specified.
@ -37,13 +38,14 @@ tb()
} }
# remove toolbx container with default or specified name. # remove toolbx container with default or specified name.
# usage: tbk [NAME]
tbk() tbk()
{ {
local name="$1" local name="$1"
# set default name. # set default name.
if [[ "$name" = "" ]]; then if [[ "$name" = "" ]]; then
name="toolbx" name="main"
fi fi
# stop and remove podman container. # stop and remove podman container.
@ -51,13 +53,14 @@ tbk()
} }
# install rpm-fusion repository. # install rpm-fusion repository.
# usage: tb_rpmfusion [NAME]
tb_rpmfusion() tb_rpmfusion()
{ {
local name="$1" local name="$1"
# set default name. # set default name.
if [[ "$name" = "" ]]; then if [[ "$name" = "" ]]; then
name="toolbx" name="main"
fi fi
# run dnf inside container. # run dnf inside container.
@ -70,7 +73,7 @@ alias tbl="toolbox list -c"
# autocomplete. # autocomplete.
_tb_containers() _tb_containers()
{ {
_autocomplete "$(toolbox list -c | sed -e '1d' | awk '{ print $2 }')" _autocomplete_first "$(toolbox list -c | sed -e '1d' | awk '{ print $2 }')"
} }
complete -F _tb_containers tb tbk tb_rpmfusion complete -F _tb_containers tb tbk tb_rpmfusion