如何仅按最左侧分隔符拆分字段?Bash+AWK数据格式化问题
问题
我尝试在Bash中用AWK实现选定记录的格式化,代码如下:
#!/bin/bash process() { declare payload="$1" declare -a keysarr=("${@:2}") ( IFS=$'|' awk 'BEGIN {FS="="; OFS="|"; ORS="~~~"} /^('"${keysarr[*]}"')/ {print $1,$2}' ) <<< "$payload" } declare sample read -r -d '' sample <<'EOF' Field1=all=1;is=2;one=3;field=4 Field2=nothing special Field3=more of the same Field4=not interested EOF process "$sample" Field1 Field2 Field3
示例包含4条记录,Field{1-4}为键,每行第一个=后的内容为对应值(比如Field1对应的值是all=1;is=2;one=3;field=4)。我需要将其重新格式化:键值用|分隔,记录用~~~分隔。目前已实现按指定键(如Field{1-3})筛选记录,但AWK的FS设为=时会拆分后续的=,导致当前输出:
Field1|all~~~Field2|nothing special~~~Field3|more of the same~~~
期望输出是保留完整值的格式:
Field1|all=1;is=2;one=3;field=4~~~Field2|nothing special~~~Field3|more of the same~~~
要求不能使用gawk,也就是无法用FPAT,有没有简单调整方案?
解决方案
核心问题是FS="="会把每行所有的=都作为分隔符,导致Field1的值只取到第一个=后的all。可以换个思路,不依赖FS拆分,而是通过字符串截取分离键和值:
修改后的完整代码如下:
#!/bin/bash process() { declare payload="$1" declare -a keysarr=("${@:2}") ( IFS=$'|' awk 'BEGIN {OFS="|"; ORS="~~~"} /^('"${keysarr[*]}"')/ { # 定位第一个=的位置 eq_pos = index($0, "=") # 截取键(开头到=前)和完整值(=后到结尾) key = substr($0, 1, eq_pos - 1) val = substr($0, eq_pos + 1) print key, val }' ) <<< "$payload" } declare sample read -r -d '' sample <<'EOF' Field1=all=1;is=2;one=3;field=4 Field2=nothing special Field3=more of the same Field4=not interested EOF process "$sample" Field1 Field2 Field3
调整说明
- 移除
FS="="设置,避免拆分后续的= - 用
index($0, "=")精准定位每行第一个=的位置 - 通过
substr分别截取键和完整值,确保值部分保留所有后续内容 - 保留原有的
OFS和ORS设置,保证输出格式符合要求
运行后即可得到期望的输出:
Field1|all=1;is=2;one=3;field=4~~~Field2|nothing special~~~Field3|more of the same~~~
内容的提问来源于stack exchange,提问作者Albert Camu
相关产品推荐
相关产品推荐

