2022-31周 bash 使用技能

编程

31 周 bash 编程技能

1. 替换变量中的 "

变量直接解析在 bash 里面,引号并不会被自动转义,所以需要手动转义 
1
sed $'s/\"/\\\"/g' 
当然,转义 `'` 一样容易
1
sed $"s/\'/\\\'/g" 
这里用的是 sed 的替换命令, 对于 sed 的使用我还不太熟练,因为经常使用的只有用 sed 删除 所以,下面这份代码有一个隐藏的 bug
1
2
3
4
5
6
7
qshell uploadfile --file-list=upload.txt --failure-list=fail.txt
res=$(cat fail.txt)
if [ -z $res ];then
echo 'these file fail!';
else:
echo "all successed!";
fi
如果你的 fail.txt 里面包含空格的话,在条件判断的地方将被展开为多个字符串参数,你可以选择用 `"` 包起来,不过indeed问题就是,如果 fail.txt 里面也包含 `"`,那么展开之后又出现了问题 所以,你需要在此处对输入进行转义,这样:
1
2
3
4
5
6
7
qshell uploadfile --file-list=upload.txt --failure-list=fail.txt
res=$(cat fail.txt | sed $'s/\"/\\\"/g')
if [ -z "$res" ];then
echo 'these file fail!';
else:
echo "all successed!";
fi

2. 在 awk 命令中包含变量:

这是一个看起来稍微有一点复杂的问题
如果,你要在 awk 中使用 bash 变量
1
awk -F '\t' '{print "'''$domain_url$sub_dir'''"$1}' test.txt > refresh.txt
假设 `domain_url` 为 http://example.com `sub_dir` 为 v1 此处,在调用 awk 的时候,命令实际上已经变成了
1
awk -F '\t' '{print http://example.com/v1/$1}' test.txt > refresh.txt
有的时候,你可以写成
1
awk -F '\t' '{print "'$domain_url$sub_dir'"$1}' test.txt > refresh.txt
....... 这个引号我已经有点晕了

3. xargs

菜鸟讲得好,懒得写了 [xargs 使用](https://www.runoob.com/linux/linux-comm-xargs.html)

4. comm 命令的使用

comm 命令可以用来比较两个文件的差异
comm -arg file1 file2
不过,使用之前,需要先 sort 一下,使用 sort 命令
sort file1
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
Usage: comm [OPTION]... FILE1 FILE2
Compare sorted files FILE1 and FILE2 line by line.

When FILE1 or FILE2 (not both) is -, read standard input.

With no options, produce three-column output. Column one contains
lines unique to FILE1, column two contains lines unique to FILE2,
and column three contains lines common to both files.

-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)

--check-order check that the input is correctly sorted, even
if all input lines are pairable
--nocheck-order do not check that the input is correctly sorted
--output-delimiter=STR separate columns with STR
--total output a summary
-z, --zero-terminated line delimiter is NUL, not newline
--help display this help and exit
--version output version information and exit

Note, comparisons honor the rules specified by 'LC_COLLATE'.

Examples:
comm -12 file1 file2 Print only lines present in both file1 and file2.
comm -3 file1 file2 Print lines in file1 not in file2, and vice versa.

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report comm translation bugs to <https://translationproject.org/team/>
Full documentation at: <https://www.gnu.org/software/coreutils/comm>
or available locally via: info '(coreutils) comm invocation'
1
comm -12 f1.txt f2.txt > bothin.txt
将会得到两个文件共同有的部分

5. 去重

网上说去重要先 sort ,然后 unique .......
但是,sort 命令仿佛就是可以去重的,使用 -u 参数
1
sort -u file.txt > sort_unique.txt
你将得到一个已经去除重复行的新文件 sort_unique.txt

6. 补充一点快忘光了的东西

重定向

我们知道,Linux 后台运行程序用 &

1
java run.jar &

也可以使用 nohup

但我今天要说的不是这个,而是,标准输出重定向符

之前看到一段代码和这有关,但是我现在死活想不起来,就先随便提一下

1
2
3
0 是一个文件描述符,表示标准输入(stdin)
1 是一个文件描述符,表示标准输出(stdout)
2 是一个文件描述符,表示标准错误(stderr)

所以:

1
2
3
4
5
6
7
ls 1> out.txt   # 结果输出到文件
ls 2> err.txt # 错误输出到文件
ls &> log.txt # 结果和错误都
# 当然,还有另一种写法
ls >& log.txt
# 等价于
ls > log.txt 2>&1

还有下面这种用法,之前用了好久,不理解怎么回事

1
ls 1>&2 > log.txt

这个实际上就是,标准输出重定向到错误输出,再重定向到 log.txt
&> 一样,
至于 & 符号,是代表描述符的意思,&2 表明 2 是一个描述符,否则,2 会被当作文件名

命名管道

趁热打铁,顺带说一下命名管道的事

bash 中可用两个命令创建命名管道 mkfifo mknode
之前看到一个反弹 shell 很神奇,现在一时想不起来了,利用管道循环不死

1
mkfifo /tmp/i

就创建了一个管道,当你向管道写入 数据,它不会返回,而是等待数据被读出

….

至于 > >> >>> < <<< 过两天再写吧,今天早点睡了。

Author: 哒琳

Permalink: http://blog.jieis.cn/2022/791d70dd-58ad-4de1-a502-fd7e6fa57f72.html

Comments