sed:'s' 的未知选项

sed:'s' 的未知选项

我正在尝试在 Bash shell 中使用 shell 脚本文件。此脚本中sed有 2 个命令。第二个sed命令如下。

sed -e s:MACRO_NAME:"${runmacro}":g \
    -e s:INFILE_PATH_NAME:"${filedir}"/"${filename}":g \
    -e s:INFILE_NAME:"${filename%.*}":g \
    -e s:INDEX:"${index}":g \
    -e s:TREE_NAME:"${treename}":g \
    -e s:SUFFIX:"${suffix}":g \
    -e s:SMEAR_TEMPLATE_NAME:"${smeartemplatename}":g \
    -e s:IS_MC:"${ismc}":g \
    -e s:PWD:.:g \
    -e s:SCRAM_DIR:"${scramdir}":g \
    -e s:OUTFILE_NAME:"${outfilename}":g \
    -e s:OUTFILE_DIR:"${outputpath}":g \
    -e s:PREFIX:"${prefix}":g \
    -e s:OUTPUT_DIR:"${outputdir}":g \
        template_files/submit_script_template.sh > tempfile \
&& mv tempfile ../"${outputdir}"/submit_"${outputdir}"_"${index}".sh

通过执行该.sh文件,我收到此错误:

sed: -e expression #2, char 25: unknown option to `s'

我也添加了echosed结果是:

sed -e s:MACRO_NAME:QCDSmearedSkimmer.C:g \
    -e s:INFILE_PATH_NAME:root://cmseos.fnal.gov//store/user/lpcstop/noreplica/13TeV/290117/Moriond17/qcd_orig//qcd_ht1000to1500-ext_10_ntuple_postproc.root:g \
    -e s:INFILE_NAME:qcd_ht1000to1500-ext_10_ntuple_postproc:g \
    -e s:INDEX:2:g \
    -e s:TREE_NAME:Events:g \
    -e s:SUFFIX:SmearedQCD:g \
    -e s:SMEAR_TEMPLATE_NAME:resTailOut_combined_filtered_CHEF_puWeight_weight_WoH.root:g \
    -e s:IS_MC:1:g \
    -e s:PWD:.:g \
    -e s:SCRAM_DIR:${CMSSW_BASE}:g \
    -e s:OUTFILE_NAME:qcd_ht1000to1500-ext_10_ntuple_postproc_1_SmearedQCD.root:g \
    -e s:OUTFILE_DIR:/ddash/nobackup/mywork/qcd/CMSSW_9_4_6_patch1/src/AnalysisMethods/macros/Skims/generate_smear_scripts/smeared_file/:g \
    -e s:PREFIX:root://cmseos.fnal.gov//:g \
    -e s:OUTPUT_DIR:qcd_smeared_file3:g \
        template_files/submit_script_template.sh > tempfile \
&& mv tempfile ../qcd_smeared_file3/submit_qcd_smeared_file3_2.sh

请帮我解决这个问题。

答案1

sed表达式s:INFILE_PATH_NAME:"${filedir}"/"${filename}":g由五个部分组成:

  • 命令,seds
  • 该命令的搜索模式 ( INFILE_PATH_NAME),
  • 替换文本(无论什么"${filedir}"/"${filename}"- 在这个例子中,都是root://cmseos.fnal.gov//store/user/lpcstop/noreplica/13TeV/290117/Moriond17/qcd_orig//qcd_ht1000to1500-ext_10_ntuple_postproc.root),
  • 命令选项s(此处g),
  • 以及将所有这些分隔开的分隔符,这里是:(冒号)。

现在,如果替换文本包含:,那么 sed 会认为替换文本到此结束,后面的内容都是 的选项s。因此,

  • 替代品:root://cmseos.fnal.gov//store/user/lpcstop/noreplica/13TeV/290117/Moriond17/qcd_orig//qcd_ht1000to1500-ext_10_ntuple_postproc.root
  • 选项:g

我们得到:

  • 替代品:root
  • 选项://cmseos.fnal.gov//store/user/lpcstop/noreplica/13TeV/290117/Moriond17/qcd_orig//qcd_ht1000to1500-ext_10_ntuple_postproc.root:g

就 sed 而言,这是无效的。

建议的解决方案:

  1. 使用不同的分隔符,一些不会出现在替换文本中的字符,例如,(逗号)、;(分号)等。例如:

    sed -e "s,INFILE_PATH_NAME,${filedir}/${filename},g" ...
    
  2. 无论您从哪里获得输入,都:用反斜杠转义,以便它变成\:

答案2

出现此错误的原因是,您的变量(至少其中一些)包含冒号 ( :),并且您使用冒号作为s/…/…/命令的分隔符。实际上,对于s:…:…:您的情况下的命令而言。

当你有

var="ex:ample"

然后尝试发出

sed -e "s:${var}:sample:g" some_file

然后 shell 在将变量交给 之前对其进行插值sed,并sed像这样调用:

sed -e "s:ex:ample:sample:g" some_file

并且s:…:…:现在已损坏。看起来您正在告诉用sed替换并应用选项、、、、和。examplesample

为了避免这种情况,请使用您确定不会出现在文本中的其他分隔符。常用的分隔符是+#,但您可以选择任何字符。分隔符实际上是后面的第一个字符s,因此

sed -e "s#…#…#" some_file
sed -e "s+…+…+" some_file
sed -e "s'…'…'" some_file

都可以。

相关内容