GCC

gcc main.c -o main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 可以随时停在某一步
gcc -E main.c -o main.i # 预处理
gcc -S main.c -o main.s # 编译
gcc -c main.c -o main.o # 汇编
gcc main.o -o main # 链接

gcc -Wall main.c -o main # 警告处理
gcc -g main.c -o main # 调试选项

# 可多个源文件同时编译
gcc main.c utils.c math.c -o main

# 指定头文件搜索路径
gcc main.c -I./include -o main

# 定义宏(-D)
gcc -DDEBUG main.c -o main # 相当于预写 "#define DEBUG"

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CC = gcc
CFLAGS = -Wall -g
TARGET = main
OBJS = main1.o main2.o main3.o

all: $(TARGET)

$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)$

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

clean:
rm -f ...

run:
./$(TARGET)

调用子目录的Makefile文件:

1
2
3
4
5
6
7
8
9
10
11
12
# 假设要用csc/Makefile运行csc/code/Makefile
CC = gcc
TARGET = fibo

all:
# 1. 进入 code 目录并执行那里的 Makefile (-C 选项用于指定目录)
$(MAKE) -C code
# 2. 将 code 目录下的 .o 文件链接为当前目录下的可执行文件 fibo
$(CC) code/fibo.o code/main.o -o $(TARGET)

clean:
rm -f code/*.o

$(MAKE): 保证make命令带的参数被传递给子目录的 Makefile

shell

1
2
3
4
5
#!/bin/bash
echo $1
echo $# # 传递的参数个数
echo $* # 一个字符串显示传递的全部参数
echo $? # 获取前一个命令的返回值

定义函数:

1
2
3
4
5
6
7
fun() {
echo "$1"
echo "$2"
echo "$#"
}

fun 1 str2 # 调用

流程控制语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# if
if <condition>
then
<command>
fi

a=1
if [ $a -ne 1 ]; then echo ok; fi

#while
a=1
while [ $a -ne 10 ]
do
mkdir file$a
let a=a+1
done

重定向与管道:

command < input.txt 1>output.txt 2>err.txt

  • 标准输出:stdout,由1表示
  • 标准错误:stderr,由2表示
  • >覆盖,>>追加

command1 | command2 | command3 | ...

cat < my.sh | grep "Hello" > output.txt

sed/awk/grep

sed

  • -n 不输出(配合p使用)
  • -i 直接修改文件
  • -e 多点编辑
  • -r 支持扩展正则表达式
  • -f 从文件中读取脚本指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 替换
sed '2s/apple/orange/gi' file.txt # 2第二行,g全局替换,i忽略大小写

# 删除
sed '2d' file.txt
sed '2,5d' file.txt
sed '/^$/d' file.txt # 删除空行
sed '/error/d' file.txt

# 打印
sed -n '/root/p' /etc/passwd

# 增加与插入
sed '$a return 0;' file.txt # 最后一行后
sed '/error/i WARNING:' file.txt # error行前插入

# 修改整行
sed '/windows/c Linux' file.txt

# 例:删除文件中的注释行(#开头)和空行
sed -i -e '/^#/d' -e '/^$/d' config.conf

# 批量修改
sed -i 's/foo/bar/g' *.txt

awk

  • $0 整行内容
  • $n 第n列
  • $NF 最后一列
  • $(NF-1) 倒数第二列
  • NF 列数

-F 指定分隔符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 提取特定列
awk '{print $1,$3}' file.txt
awk '{print NF,$1}' file.txt

# 格式化输出
awk '{printf "Row: %-3d Name: %-10s\n, NR, $1"}' file.txt

# 条件过滤
awk '$3 > 100 {print $0}' data.txt
awk '$2 == "root" {print $0}' /etc/passwd
awk '$3 > 50 && $4 < 100' data.txt

# 正则匹配
awk '$2 ~ /Smith/ {print $0}' names.txt
awk '$3 !~ /[0-9]/' data.txt
awk '/start/, /end/ {print $0}' file.txt

grep

  • -i 忽略大小写
  • -v 反向匹配
  • -w 全词匹配
  • -x 整行匹配
  • -n 显示行号
  • -c 统计行数
  • -r 递归搜索
  • –include 指定只搜特定文件
  • –exclude 排除特定文件或目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 在项目中查找“TODO”
grep -rn "TODO" . --exclude-dir=.git

# 查看配置文件
grep -vE "^#|^$" /etc/nginx/nginx.conf

# 统计某IP出现次数
grep -c "192.168.1.1" access.log

# 提取所有IPv4地址
grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log

# 同时搜索多个关键词
grep -e "error" -e "fail" log.txt # error或fail出现
grep "error" log.txt | grep "database" # error和fail同时出现

cut

1
2
cut -d ',' -f 2 data.csv
grep -n "Mark" file.txt | cut -d ':' -f 1 result.txt