在我几年前编写的bash个干净的脚本中,我有以下sed个范围替换表达式,它在旧环境中有效(或至少从未出错),但在新环境中失败(有错误),并且我无法确定为什么新旧环境之间的范围无效.

该表达式的目的是从用于将数据导入数据库的TSV文件中删除不需要的Unicode或控制字符.

单行中的表达式示例:

sed -e 's,[\x00\x01-\x08\x0a-\x1f\x7f]\+,,g' file.tsv
  • 旧环境:Ubuntu v16.04、Bash v4.3.46、GNU SED v4.2.2
  • 新环境:Ubuntu v20.04、Bash v5.0.17、GNU SED v4.7

仅在新环境中出错(在旧环境中没有错误):

/usr/bin/sed: -e expression #1, char 35: Invalid range end

我try 在https://www.jdoodle.com/test-bash-shell-script-online上运行该表达式,并 Select 使用sed v4.7的bashv5.0.011,但没有产生错误,因此可能不是sed或bash的版本问题.

我记不起我是如何组成所用的字符范围的,也记不清为什么有两个范围(两个),但我觉得我知道很多年前就能有效地组成它.现在,在迁移到运行脚本的新的停靠容器环境时,我正在try 记住和诊断这一点.

Questions:

为什么这在一种环境中会失败,而在另一种环境中不会呢?

有没有可能这个表达式需要的不是sed等版本,而是我在旧环境中所做的设置?如果你对此有什么 idea ,我可以判断和测试.

Note:我实际上不需要特定的内容来测试这一点,我只需运行上面的示例,而不使用‘file.tsv’或空文件,它将在新环境中产生相同的错误.

推荐答案

编辑:TL;DR:

sed 's,[\x00\x01-\x08\x0a\x0b\x0c\x0d\x0e-\x1f\x7f]\+,,g' /dev/null

是解决此问题的一种方法.在区域设置处理和范围的交叉点上有一些问题,如果您完全关闭区域设置处理,这部分没有问题,但您没有得到您的Unicode好处,试图绕过范围审查代码中的任何故障使我找到了可以工作的代码.

我是如何到达那里的:


我试过了,没有得到,然后我寻找错误.我做了\x10次因为我脑子里有巫术.

$ LC_ALL=en_US.UTF8 sed 's,[\x00\x01-\x08\x10-\x1f\x7f]\+,,g' /dev/null
$ LC_ALL=en_US.UTF8 sed 's,[\x00\x01-\x08\x0a-\x1f\x7f]\+,,g' /dev/null
sed: -e expression #1, char 35: Invalid range end
$ LC_ALL=C sed 's,[\x00\x01-\x08\x0a-\x1f\x7f]\+,,g' /dev/null
$

这是区域设置处理中的某个奇怪的错误.跑LC_ALL=C米对我来说很管用.

此外,使用范围,单独指定\x7f也可以绕过它,而不需要切换区域设置.

$ sed 's,[\x00\x01-\x08\x0a-\x7e\x7f]\+,,g' /dev/null
$ 

我try 在https://www.jdoodle.com/test-bash-shell-script-online上运行该表达式,并 Select 使用sed v4.7的bashv5.0.011,但没有产生错误,因此可能不是sed或bash的版本问题.

但是,当我在命令前面添加LC_ALL=en_US.UTF8时,它确实会在那里弹出错误.

Linux相关问答推荐

C++ kill()使Linux崩溃到登录屏幕

Bash脚本用于在远程工作后关闭用户会话

为什么硬编码的阿拉伯字母与Unicode代码点不具有相同的值

并行函数的最后一个实例的状态

Git在某些文件中添加回车符,尽管autocrlf已关闭

如何在具有多种可能性的linux shell中获取最大值和最小值?

Qt会泄漏内存吗?

在服务器目录之外启动 DolphinDB 服务器时出错

进程Forking 后 pthread_key_create() 生成的密钥会发生什么?

在 bash 中查找匹配多个模式的文件

增加 mysql docker 中的 max_allowed_pa​​cket 大小

在 VIM 中搜索和替换导致尾随字符

如何通过 ssh 判断 ubuntu 服务器上是否存在 php 和 apache

使用 cmake 构建错误:找不到 -lpthreads

从linux命令行写入串口

./studio.sh 之后的 Android Studio 错误

命令列出除 . (点)和..(点点)

try 使用 sudo 将文件附加到根拥有的文件时权限被拒绝

如何以编程方式禁用硬件预取?

Bash:等待超时