You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Korn Shell中如何将用户输入日期变量传入sed命令

问题:Korn Shell中sed命令无法传入变量导致执行错误

在Korn Shell环境下,我通过accept_date.ksh脚本获取用户输入的日期并存入broken_date变量,但把这个变量传入sed命令批量修改文本文件指定位置的日期时,出现了sed: unknown command错误。原静态sed命令可以正常生效,修改后就报错了。

示例文本

126731E             0000000033220422    000003312634460-0003-1
134180D             0000000052220419    000006012622399-0003-1
 134307-004K         0000000016220420    000001612635621-0003-0
 141014-001B         0000000040220419    000004012632585-0003-0
134886C             0000000034220419    000007612620821-0003-1
 123899B             0000000050220412    000005012635007-0003-1
121543C             0000000059220419    000007512621925-0003-1
 118238C             0000000070220419    000007012632584-0003-0
121852A             0000000122220419    000013512622569-0003-1
 123124A             0000000141220419    000014112631954-0003-0
 123157C             0000000344220422    000034412634707-0003-1

期望结果

126731E             0000000033220422    000003312634460-0003-1
134180D             0000000052220102    000006012622399-0003-1
 134307-004K         0000000016220420    000001612635621-0003-0
 141014-001B         0000000040220419    000004012632585-0003-0
134886C             0000000034220102    000007612620821-0003-1
 123899B             0000000050220412    000005012635007-0003-1
121543C             0000000059220102    000007512621925-0003-1
 118238C             0000000070220419    000007012632584-0003-0
121852A             0000000122220102    000013512622569-0003-1
 123124A             0000000141220419    000014112631954-0003-0
 123157C             0000000344220422    000034412634707-0003-1

当前脚本片段

export GLOBAL_UTILS="../../utils"

broken_date=`$GLOBAL_UTILS/accept_date.ksh "$title" "$message" "$btn_width" "$btn_1_txt" "$btn_2_txt"`
print $broken_date

sed -f  [^ ]\+0\+\([1-9]\)\([0-9]\{1,3\}\)\([0-9]\{6\}\)0\+\1\?\2/!{s/[0-9]\{6\}/"$broken_date"/ ../1111003.txt > new.txt

原静态sed命令

/[^ ]* \+0\+\([1-9]\)\([0-9]\{1,3\}\)\([0-9]\{6\}\).* 0\+\1\?\2/!{
    s/[0-9]\{6\} /220102 /
}

报错信息

+ + echo 220909
RESULT=220909
+ break
+ + echo 220909
+ bc
date_in=220909
+ [ 220909 -lt 200101 ]
+ [ 220909 -gt 501231 ]
+ dlg close
+ break
+ echo 220909
broken_date=220909
  print $broken_date
+ print 220909
220909

    sed -Ee "/[^ ]* +0+([1-9])([0-9]{1,3})([0-9]{6}).* 0+\1?\2/ ! {s/[0-9]{6} /$broken_date /" -e '}' ../1111003.txt > .
./new.txt
+ sed -Ee /[^ ]* +0+([1-9])([0-9]{1,3})([0-9]{6}).* 0+\1?\2/ ! {s/[0-9]{6} /220909 / -e } ../1111003.txt
sed: unknown command

问题根源

  1. sed命令语法混乱:当前脚本里的sed命令没有用引号包裹完整逻辑,导致shell解析时把sed的命令拆成了多个无效参数,比如单独的}被当成了sed命令,引发"未知命令"错误。
  2. 变量引用方式错误:没有正确处理sed中变量的替换逻辑,同时原静态命令的正则转义在带变量的写法里没有适配好。

修正后的可行写法

写法1:用双引号包裹完整sed命令

sed -E "/[^ ]* +0+([1-9])([0-9]{1,3})([0-9]{6}).* 0+\1?\2/!{s/[0-9]{6} /$broken_date /}" ../1111003.txt > new.txt
  • 用双引号包裹整个sed命令,shell会先替换$broken_date变量,同时保证sed的逻辑作为一个整体被解析,不会被拆分。
  • 添加-E参数启用扩展正则表达式,这样正则里的+、{}不需要转义,和原静态命令逻辑保持一致。

写法2:用临时文件存放sed脚本(适合复杂逻辑)

如果sed的逻辑更复杂,可先把脚本写入临时文件再调用:

# 生成sed脚本临时文件
cat > sed_script.tmp << EOF
/[^ ]* +0+([1-9])([0-9]{1,3})([0-9]{6}).* 0+\1?\2/!{
    s/[0-9]{6} /$broken_date /
}
EOF
# 执行sed命令
sed -E -f sed_script.tmp ../1111003.txt > new.txt
# 删除临时文件
rm -f sed_script.tmp
  • 通过here-document生成脚本文件,$broken_date会被自动替换成变量值。
  • sed通过-f参数读取脚本文件执行,避免了命令行的语法混乱问题。

关键注意事项

  • 必须用-E:启用扩展正则表达式,否则需要给+、{}加转义符,容易出错。
  • 引号选双引号:单引号会阻止shell替换变量,双引号既能替换变量又能保留sed命令的完整性。
  • 不要拆分sed逻辑:原脚本里把}单独作为-e参数是错误的,sed的命令块必须作为一个整体。

内容的提问来源于stack exchange,提问作者fletching

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:45:31