linux ex命令

ex命令 是Linux系统中的行文本编辑器,是vi编辑器的前身,提供强大的行编辑功能。

命令简介

ex是Unix和Linux系统中的行文本编辑器,它是vi编辑器的直接前身。ex提供基于行的编辑命令,支持强大的文本处理功能。虽然现在较少直接使用,但了解ex命令对于深入理解vi/vim编辑器的工作原理非常有帮助。

语法格式

ex [选项] [文件]

常用选项

选项 说明
-v 启动vi编辑器(可视模式)
-c command 在启动时执行指定的ex命令
-r 恢复崩溃的编辑会话
-R 只读模式
-l LISP模式
-s 静默模式(批处理)
-w size 设置窗口大小
--help 显示帮助信息
--version 显示版本信息

基本命令

命令 说明
a 在当前行后追加文本
i 在当前行前插入文本
c 修改当前行
d 删除行
p 打印(显示)行
w 写入(保存)文件
q 退出编辑器
wq 保存并退出
q! 强制退出(不保存)
s/old/new/ 替换文本
/pattern/ 向前搜索模式
?pattern? 向后搜索模式
. 当前行
$ 最后一行
set number 显示行号
set nonumber 隐藏行号

地址表示法

ex使用地址来指定要操作的行:

.       当前行
$       最后一行
n       第n行
+n      当前行后的第n行
-n      当前行前的第n行
,       所有行(1,$)
;       从当前行到最后一行(.,$)
/regex/ 匹配正则表达式的行
%       所有行(1,$)的简写

使用示例

示例1:基本编辑会话

启动ex并创建新文件:

# 启动ex编辑器
ex newfile.txt

# 在ex中的操作:
# 进入输入模式
a
这是第一行。
这是第二行。
这是第三行。
.  # 退出输入模式(单独一行输入点号)

# 显示所有内容
1,$p

# 保存文件
w

# 退出
q

示例2:编辑现有文件

打开并编辑现有文件:

# 创建测试文件
echo -e "第一行\n第二行\n第三行\n第四行\n第五行" > example.txt

# 使用ex编辑文件
ex example.txt

# 在ex中的操作:
# 显示内容
1,$p
# 删除第2-4行
2,4d
# 显示修改后的内容
1,$p
# 保存并退出
wq

示例3:搜索和替换

使用搜索和替换功能:

# 创建包含特定文本的文件
echo -e "hello world\nhello linux\nhello editor" > text.txt

# 使用ex进行替换
ex text.txt << 'EOF'
1,$s/hello/hi/g  # 全局替换hello为hi
1,$p              # 显示结果
w                 # 保存
q
EOF

# 查看修改后的文件
cat text.txt

示例4:行操作和移动

进行各种行操作:

# 创建测试文件
seq 1 5 > numbers.txt

# 使用ex进行行操作
ex numbers.txt << 'EOF'
3i                # 在第3行前插入
3.5               # 插入的内容
.                 # 退出插入模式
5d                # 删除第5行
2,3m4             # 将第2-3行移动到第4行后
1,$p              # 显示所有行
w                 # 保存
q
EOF

cat numbers.txt

示例5:使用地址范围

使用地址范围进行批量操作:

# 创建多行文件
echo -e "line1\nline2\nline3\nline4\nline5" > data.txt

# 使用地址范围
ex data.txt << 'EOF'
2,4p              # 显示第2-4行
2,4s/line/LINE/g  # 在第2-4行中替换line为LINE
1,$p              # 显示所有行
2,4co$            # 将第2-4行复制到文件末尾
1,$p              # 显示所有行
w
q
EOF

cat data.txt

示例6:在脚本中使用ex

在Shell脚本中使用ex进行批处理:

#!/bin/bash

# 使用ex批量修改配置文件
update_config() {
    local config_file=$1
    local key=$2
    local value=$3

    ex -s "$config_file" << EOF
/^$key=/d
a
$key=$value
.
w
q
EOF
}

# 创建示例配置文件
echo -e "HOST=localhost\nPORT=8080\nDEBUG=false" > app.conf

# 修改配置
update_config "app.conf" "PORT" "9090"
update_config "app.conf" "DEBUG" "true"

echo "修改后的配置:"
cat app.conf

实际应用场景

场景1:自动化配置修改

在部署脚本中自动修改配置文件:

#!/bin/bash

# 自动更新多个配置文件
update_configurations() {
    echo "开始更新配置文件..."

    # 更新nginx配置
    if [ -f "/etc/nginx/nginx.conf" ]; then
        ex -s "/etc/nginx/nginx.conf" << 'EOF'
/worker_processes/
s/worker_processes.*/worker_processes 4;/
w
q
EOF
        echo "nginx配置已更新"
    fi

    # 更新系统限制
    if [ -f "/etc/security/limits.conf" ]; then
        ex -s "/etc/security/limits.conf" << 'EOF'
$a
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
.
w
q
EOF
        echo "系统限制已更新"
    fi
}

update_configurations

场景2:文本转换和格式化

使用ex进行文本格式转换:

#!/bin/bash

# 将文本转换为HTML格式
convert_to_html() {
    local input_file=$1
    local output_file=$2

    echo "转换文本到HTML..."

    # 使用ex进行转换
    ex -s "$input_file" << 'EOF'
1i
<html>
<body>
<pre>
.
$a
</pre>
</body>
</html>
.
1,$s/&/&/g
1,$s//>/g
w "$output_file"
q
EOF

    echo "转换完成: $output_file"
}

# 创建示例文本文件
echo -e "标题\n====\n\n这是内容部分。\n包含<特殊>字符&符号。" > document.txt

# 执行转换
convert_to_html "document.txt" "output.html"
cat output.html

场景3:代码重构

使用ex进行代码批量修改:

#!/bin/bash

# 批量重命名函数
refactor_functions() {
    local source_dir=$1
    local old_name=$2
    local new_name=$3

    echo "重构函数: $old_name → $new_name"

    # 在所有源文件中重命名函数
    find "$source_dir" -name "*.c" -o -name "*.h" | while read file; do
        echo "处理: $file"
        ex -s "$file" << EOF
1,$s/\<${old_name}\>(\s*)/${new_name}\1/g
w
q
EOF
    done

    echo "重构完成"
}

# 使用函数(示例)
# refactor_functions "src/" "old_func" "new_func"

高级用法

使用全局命令

使用g命令进行全局操作:

# 创建测试文件
echo -e "error: file not found\nwarning: deprecated\ninfo: started\nerror: permission denied" > messages.txt

# 使用全局命令
ex messages.txt << 'EOF'
g/^error/p        # 打印所有以error开头的行
g/^error/d        # 删除所有以error开头的行
1,$p               # 显示剩余内容
g/^warning/s/warning/WARNING/  # 将warning替换为WARNING
1,$p
w
q
EOF

使用标记和导航

使用标记来记住位置:

# 创建多章节文件
echo -e "Chapter 1\nContent A\nContent B\nChapter 2\nContent C" > book.txt

# 使用标记导航
ex book.txt << 'EOF'
/Chapter 1/       # 搜索到第一章
ka                # 标记当前位置为a
/Chapter 2/       # 搜索到第二章
'a,$p             # 从标记a到文件末尾打印
'a,'a+2p          # 打印标记a后的2行
q
EOF

复杂替换模式

使用高级替换功能:

# 创建包含各种格式的文件
echo -e "Name: John Doe\nAge: 30\nEmail: john@example.com" > contact.txt

# 使用分组和反向引用
ex contact.txt << 'EOF'
1,$s/\(Name\): \(.*\)/\2 (\1)/  # 重新格式化Name行
1,$s/\(.*\): \(.*\)/[\1] = "\2"/ # 添加方括号和引号
1,$p
w
q
EOF

cat contact.txt

与vi的关系

ex和vi实际上是同一个程序的不同界面:

# 从ex切换到vi模式
ex filename
:visual          # 切换到vi模式

# 从vi切换到ex模式
vi filename
:ex              # 切换到ex模式
Q                # 从vi直接进入ex模式

注意事项

  • ex是面向行的编辑器,适合处理结构化文本
  • 在输入模式中,单独一行输入.来退出输入模式
  • 修改后必须使用w命令保存,否则更改会丢失
  • 使用q!命令可以强制退出而不保存
  • ex的正则表达式语法与sed类似
  • 在脚本中使用时,建议使用-s选项(静默模式)
  • ex在处理二进制文件时可能产生意外结果
  • 大多数ex命令在vi中也可以使用(在命令模式下)

常见问题解决

在单独一行输入点号.退出输入模式:

# 正确退出输入模式的方法
a                    # 进入追加模式
这是输入的文字
.                    # 单独一行输入点号,退出输入模式

# 如果卡在输入模式,可以按Ctrl+C中断
# 或者按Ctrl+D(但可能退出编辑器)

检查正则表达式和分隔符:

# 基本的替换语法
s/old/new/          # 替换当前行的第一个old为new
s/old/new/g         # 替换当前行的所有old为new

# 使用不同的分隔符(当文本包含/时很有用)
s|old|new|g         # 使用|作为分隔符
s#old#new#g         # 使用#作为分隔符

# 确认替换范围
1,$s/old/new/g      # 在整个文件中替换

处理文件写入权限问题:

# 检查文件权限
ls -l filename

# 使用强制写入(如果可能)
w!                  # 强制写入

# 另存为新文件
w newfilename

# 如果文件只读,先修改权限
:!chmod +w filename
:w

相关命令

命令 说明 区别
vi 可视编辑器 ex的可视化版本,全屏编辑
vim 改进的vi编辑器 vi的增强版本,功能更丰富
ed 行编辑器 ex的前身,命令更基础
sed 流编辑器 非交互式,适合管道操作
awk 文本处理语言 更适合复杂的数据处理

历史意义

ex编辑器在Unix历史中具有重要地位,它是vi编辑器的基础。虽然现在很少直接使用ex进行交互式编辑,但了解ex对于理解vi/vim的工作原理和掌握高级文本编辑技巧很有帮助。许多vi命令实际上就是ex命令。