全宇宙最全的Linux运维bash脚本常见用法总结

删除重复的数组元素创建临时关联数组 。设置关联数组
值并发生重复赋值时,bash会覆盖该键 。这
允许我们有效地删除数组重复 。
CAVEAT:需要bash4+
示例功能:
remove_array_dups() {# Usage: remove_array_dups "array"declare -A tmp_arrayfor i in "$@"; do[[ $i ]] && IFS=" " tmp_array["${i:- }"]=1doneprintf '%sn' "${!tmp_array[@]}"}用法示例:
$ remove_array_dups 1 1 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 512345$ arr=(red red green blue blue)$ remove_array_dups "${arr[@]}"redgreenblue随机数组元素示例功能:
random_array_element() {# Usage: random_array_element "array"local arr=("$@")printf '%sn' "${arr[RANDOM % $#]}"}用法示例:
$ array=(red green blue yellow brown)$ random_array_element "${array[@]}"yellow# Multiple arguments can also be passed.$ random_array_element 1 2 3 4 5 6 73循环一个数组每次printf调用时,都会打印下一个数组元素 。当
打印到达最后一个数组元素时,它
再次从第一个元素开始 。
arr=(a b c d)cycle() {printf '%s ' "${arr[${i:=0}]}"((i=i>=${#arr[@]}-1?0:++i))}在两个值之间切换这与上面的工作方式相同,这只是一个不同的用例 。
arr=(true false)cycle() {printf '%s ' "${arr[${i:=0}]}"((i=i>=${#arr[@]}-1?0:++i))}LOOPS循环一系列数字替代seq 。
# Loop from 0-100 (no variable support).for i in {0..100}; doprintf '%sn' "$i"done循环遍历可变数字范围替代seq 。
# Loop from 0-VAR.VAR=50for ((i=0;i<=VAR;i++)); doprintf '%sn' "$i"done循环数组arr=(Apples oranges tomatoes)# Just elements.for element in "${arr[@]}"; doprintf '%sn' "$element"done循环遍历带索引的数组arr=(apples oranges tomatoes)# Elements and index.for i in "${!arr[@]}"; doprintf '%sn' "${arr[i]}"done# Alternative method.for ((i=0;i<${#arr[@]};i++)); doprintf '%sn' "${arr[i]}"done循环遍历文件的内容while read -r line; doprintf '%sn' "$line"done < "file"循环遍历文件和目录不要用ls 。
# Greedy example.for file in *; doprintf '%sn' "$file"done# PNG files in dir.for file in ~/Pictures/*.png; doprintf '%sn' "$file"done# Iterate over directories.for dir in ~/Downloads/*/; doprintf '%sn' "$dir"done# Brace Expansion.for file in /path/to/parentdir/{file1,file2,subdir/file3}; doprintf '%sn' "$file"done# Iterate recursively.shopt -s globstarfor file in ~/Pictures/**/*; doprintf '%sn' "$file"doneshopt -u globstar文件处理CAVEAT: bash在版本中不能正确处理二进制数据< 4.4 。
将文件读取为字符串替代cat命令 。
file_data=https://www.isolves.com/it/rj/czxt/linux/2022-03-18/"$(<"file")"将文件读取到数组(按行)替代cat命令 。
# Bash <4IFS=$'n' read -d "" -ra file_data < "file"# Bash 4+mapfile -t file_data < "file"获取文件的前N行替代head命令 。
CAVEAT:需要bash4+
示例功能:
head() {# Usage: head "n" "file"mapfile -tn "$1" line < "$2"printf '%sn' "${line[@]}"}用法示例:
$ head 2 ~/.bashrc# PromptPS1='? '$ head 1 ~/.bashrc# Prompt获取文件的最后N行替代tail命令 。
CAVEAT:需要bash4+
示例功能:
tail() {# Usage: tail "n" "file"mapfile -tn 0 line < "$2"printf '%sn' "${line[@]: -$1}"}用法示例:
$ tail 2 ~/.bashrc# Enable tmux.# [[ -z "$TMUX"]] && exec tmux$ tail 1 ~/.bashrc# [[ -z "$TMUX"]] && exec tmux获取文件中的行数替代wc -l 。
示例函数(bash 4):
lines() {# Usage: lines "file"mapfile -tn 0 lines < "$1"printf '%sn' "${#lines[@]}"}示例函数(bash 3):
此方法使用的内存少于mapfile方法,并在bash3中工作,但对于较大的文件,它的速度较慢 。
lines_loop() {# Usage: lines_loop "file"count=0while IFS= read -r _; do((count++))done < "$1"printf '%sn' "$count"}用法示例:
$ lines ~/.bashrc48$ lines_loop ~/.bashrc48计算目录中的文件或目录这是通过将glob的输出传递给函数然后计算参数的数量来实现的 。


推荐阅读