在 shell 脚本中使用 sed 命令获取子字符串并替换需要的位置

Using sed command in shell script for substring and replace position to need

我正在处理文本文件中的数据,我找不到使用 sed 的方法 select 固定位置的子字符串并替换它。

这是我的:

X|001200000000000000000098765432|1234567890|TQ

这是我需要的:

‘X’,’00000098765432’,’1234567890’,’TQ’

sed 中的以下代码给出了我需要的子字符串 (00000098765432) 但没有覆盖需要的位置

echo “ X|001200000000000000000098765432|1234567890|TQ” | sed “s/
*//g;s/|/‘,’/g;s/^/‘/;s/$/‘/“

你能帮帮我吗?

我会用 awk 而不是 sed

echo "X|001200000000000000000098765432|1234567890|TQ" | awk 'BEGIN {FS="|";OFS=","} {print ,substr(,17,14),,}'

给出输出:

X,00000098765432,1234567890,TQ

这是它的工作原理:

FS = 字段分隔符(在输入中)

OFS = 输出字段分隔符(您希望输出分隔的方式)

BEGIN -> 将其视为设置配置的地方。它只运行一次。所以你是说你希望输出以逗号分隔,输入以竖线分隔。

substr(,17,14) -> 取 $2(即第二个字段 - awk 从 1 开始计数 - 然后在其上应用子字符串。17 表示起始字符位置,14 表示从该位置开始的字符数)

在我看来,这比您拥有的 sed 版本更具可读性和可维护性。

如果要加引号,我还是用awk

$: awk -F'|' 'BEGIN{q="7"} {print  q  q","q substr(,17,14) q","q  q","q  q"\n"}' <<< "X|001200000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'

如果你只是想用sed,注意你上面要去掉16个字符,但实际上你只去掉了14个。

$: sed -E "s/^(.)[|].{14}([^|]+)[|]([^|]+)[|]([^|]+)/'','','',''/" <<< "X|0012000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'

使用sed

$ sed "s/|\(0[0-9]\{15\}\)\?/','/g;s/^\|$/'/g" input_file
'X','00000098765432','1234567890','TQ'
awk -v del1="7" \
    -v del2="," \
    -v start="3" \
    -v len="17" \
    '{
         gsub(substr([=10=],start+1,len),"");
         gsub(/[\|]/,del1 del2 del1);
         print del1[=10=]del1
    }' input_file

'X',00000098765432','1234567890','TQ'

使用任何 POSIX awk:

$ echo 'X|001200000000000000000098765432|1234567890|TQ' |
awk -F'|' -v OFS="','" -v q="'" '{sub(/.{16}/,"",); print q [=10=] q}'
'X','00000098765432','1234567890','TQ'

没有我希望的那么优雅,但它完成了工作:

'X','00000098765432','1234567890','TQ'

    # gawk profile, created Mon May  9 21:19:17 2022
    # BEGIN rule(s)

    'BEGIN {
     1     _ = sprintf("%*s", (__ = +2)^++__+--__*++__,__--)
     1            gsub(".", "[0-9]", _)
     1             sub("$",     "$", _)
     1    FS = "[|]"
     1   OFS = ","
    }

    # Rule(s)

     1     (NF *= NF == __*__) * sub(_,  "|&",   $__) * \
        sub("^.*[|]", "", $__) * sub(".+", "&")    }'

已在 gnu gawk 5.1.1mawk 1.3.4mawk 1.9.9.6macosx nawk

上进行测试和确认

The 4Chan Teller