从文件中删除特殊字符并维护字段分隔符

从文件中删除特殊字符并维护字段分隔符

我已经能够从固定长度文件中删除第一列中出现的所有特殊字符,但结果是所有后续列都向左移动了删除的字符数。它是一个空格分隔的文件。输入文件中的第 1 行已损坏。第 2 行应该是这样的。字符串 000022000362700 在两行中均从位置 49 开始。我遇到的问题是,删除 3 个特殊字符后,该字段移动到位置 46。

GAVISCON 液体薄荷 ÎOT 000022000362700 159588000007979400 50001584182 0006S020000
GAVISCON 液体薄荷 OT 000022000362700 159588000007979400 50001584182 0006S020000

我正在使用的命令如下:

cat file.txt | grep '[^ - ~]' | sed's/[^ - ~]//g'

这会产生以下输出:

    GAVISCON LIQUID PEPPERMINT OT        000022000362700   159588000007979400  50001584182        0006S020000

通过删除特殊字符,已更改字段右侧的每个字段都已移至左侧,从而更改了字段起始位置。

我已经搜索了一段时间,但找不到解决此问题的任何方法。

我应该如何进行?

答案1

使用这个命令:

sed -r 's/(\^|-|~)/ /g' file.txt
  • sed -r

    -r, --regexp-extended
    在脚本中使用扩展正则表达式

  • / /空格作为字段分隔符(或任何其他字符串)

  • (\^|-|~)

    • 第一捕获组(\^|-|~)

      • 第一种选择:\^

        \^^字面匹配字符

      • 第二种选择:-

        --字面匹配字符

      • 第三种选择:~

        ~~字面匹配字符

另一种变体是这样的(Thx@科斯塔斯):

sed 's/[-~^]/ /g' file.txt
  • [^-~]

    • [-~^]匹配下面列表中存在的单个字符

      -~^列表中的单个-~^字符

答案2

sed's/[^ - ~]//g'可能不是您使用的命令,因为它只会抱怨无效的命令。永远复制粘贴!

我猜你真的跑了sed 's/[^ -~]//g'。这会将任何不是可打印 ASCII 字符的字符替换为空字符串。换句话说,这将删除所有不可打印 ASCII 字符的字符。 (请注意,这在默认区域设置中是正确的,即在 下LC_ALL=C,但在许多其他区域设置中并非如此。)

要保持列对齐,请将每个不可打印字符替换为空格。

sed 's/[^ -~]/ /g'

由于您的grep命令,只有包含不可打印字符的行才会出现在输出中。你不需要那个grep。将所有行传递给sed;不需要修改的行将出现在输出中的正确位置。

<file.txt LC_ALL=C sed 's/[^ -~]/ /g' >new-file.txt

这会在列中间添加空格,例如您最终会得到

GAVISCON LIQUID PEPPERMINT    OT        000022000362700   159588000007979400  50001584182        0006S020000

如果您希望空格结束在列的右侧,即

GAVISCON LIQUID PEPPERMINT OT           000022000362700   159588000007979400  50001584182        0006S020000

您将需要一种不同的方法,您可以在其中指示列的停止位置。虽然这可以在 sed 中完成,但在 awk 中要容易得多。以下是如何从第一列中删除不可打印的字符并保留从位置 49 开始的其他列中的数据。

<file.txt LC_ALL=C awk '{
    first_column = substr($0, 1, 48);
    gsub(/[^ -~]/, "", first_column);
    printf "%-48s%s\n", first_column, substr($0, 49)
}' >new-file.txt

相关内容