格式化过长的行

可以直接使用 fmt 命令,或者使用下面的脚本,借助了 nroff 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
# fmt: used to format text lines
# -w width 指定宽度
# -h 是否启用连字符

while getopts "hw:" opt; do
case "${opt}" in
h) hype=1 ;;
w) width="$OPTARG" ;;
*) echo "ignore unknow argument: $opt" ;;
esac
done

shift $(($OPTIND - 1))

nroff <<EOF
.ll ${width:-72} # set up default value
.na
.hy ${hype:-0}
.pl 1
$(cat "$@")
EOF

exit 0

显示目录内容

脚本的作用在于打印出目录下的文件块大小(每个块 1024 字节)或目录下的条目个数。

在打印出所有的内容前,为了使得输出的每行展示两列, 并进行对齐,使用了如下的步骤:

  1. 使用了 sed 流文本编辑器命令,先将原始输出的两行变为一行,再将可能包含的空格字符先替换为 \0 null 字符(具体的过程见后面的注释)
  2. 使用 awk 命令格式化输出

sed 命令真是一个非常有趣的命令!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env bash

if [[ $# -gt 1 ]]; then
echo "Usage: $0 [dirname]"
exit 1
elif [[ $# -eq 1 ]]; then
cd "$@"
# if cd command failed because it is not a valid path
if [[ $? -ne 0 ]]; then
exit 1
fi
fi

# shell will extend '*' as all files and directories under the current directory
for file in *; do
if [[ -d "$file" ]]; then
size=$(ls "$file" | wc -l | sed 's/[^[:digit:]]//g')
echo "$file ($size entr(y|ies))"
else
size=$(ls -sk $file | awk '{print $1}')
echo "$file (${size}KB)"
fi
done | \
sed -n \
-e '$!N' \
-E -e 's/\n/\x0/g' \
-e 'p' | \
awk -F "\0" '{ printf "%-39s %-39s\n",$1,$2 }'

### a bettern output fotmat

## step 1: use sed to make things easy and right
# -n disable automatic priting
# '$!N' append the next line of input into the pattern space, now we have two lines in sed's pattern space
# 's/\n/\x0/g' replace '\n' in pattern space, so we make two lines a line separated by '\0'
# 'p' print the content of pattern space

### step 2: awk final output
# make the '\0' as field delimiter, and format the output

测试结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
guo@DESKTOP-4L69AND:/mnt/e/learning-dir/shell-learning/scripts$ sudo ./formatDir.sh /
bin (171 entr(y|ies)) boot (0 entr(y|ies))
dev (210 entr(y|ies)) dump-new.rdb (8KB)
etc (189 entr(y|ies)) home (1 entr(y|ies))
init (620KB) lib (22 entr(y|ies))
lib64 (1 entr(y|ies)) media (0 entr(y|ies))
mnt (8 entr(y|ies)) opt (6 entr(y|ies))
proc (46 entr(y|ies)) root (0 entr(y|ies))
run (11 entr(y|ies)) sbin (220 entr(y|ies))
snap (0 entr(y|ies)) srv (0 entr(y|ies))
sys (10 entr(y|ies)) tmp (79 entr(y|ies))
usr (8 entr(y|ies)) var (13 entr(y|ies))
zookeeper_server.pid (0KB)

提醒工具

添加提醒

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env bash
# 简单的命令行提醒工具

remindFile="$HOME/.remind"

if [ $# -eq 0 ]; then
echo "enter note and end with ctrl-D:" # ctrl-D Terminate input, or exit shell 终止输入或退出 shell
cat - >>$remindFile
else
echo "$@" >>$remindFile
fi

exit 0

查询提醒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env bash
# remindMe 查看提醒

remindFile="$HOME/.remind"

if [ ! -f $remindFile ]; then
echo "$0: You don't have a .remind file under your user home" >/dev/stderr
exit 1
fi

if [ $# -eq 0 ]; then
more $remindFile
else
grep -i -- "$@" $remindFile | ${PAGER:-more} # 变量为空默认赋值,即使用 more 命令来展示内容;-- 将后面参数不再作为 grep 命令的参数来解析,出于安全执行命令考虑
fi

exit 0

交互式包装器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env bash
# frontBc 交互式计算器,这里我只是为了参考源代码的编写方式,即如何实现一个简单的交互式包装器、

function show_help() {
cat <<EOF
This is a help documentation, supported commands are as follows:
(1) del del an item
(2) add add a new item
(3) mov move a item
EOF
}

echo "enter 'help' for help, 'quit' to quit"
echo -n "calc> "

while read command args; do
case $command in
quit | exit | bye) exit 0 ;;
help | ?) show_help ;;
*) echo "$command $args" ;;
esac
echo -n "calc> "
done

echo ""
exit 0