我正在尝试在 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'
我也添加了echo
。sed
结果是:
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
由五个部分组成:
- 命令,
sed
s
- 该命令的搜索模式 (
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 而言,这是无效的。
建议的解决方案:
使用不同的分隔符,一些不会出现在替换文本中的字符,例如
,
(逗号)、;
(分号)等。例如:sed -e "s,INFILE_PATH_NAME,${filedir}/${filename},g" ...
- 无论您从哪里获得输入,都
:
用反斜杠转义,以便它变成\:
。
答案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
替换并应用选项、、、、和。ex
ample
s
a
m
p
l
e
为了避免这种情况,请使用您确定不会出现在文本中的其他分隔符。常用的分隔符是+
和#
,但您可以选择任何字符。分隔符实际上是后面的第一个字符s
,因此
sed -e "s#…#…#" some_file
sed -e "s+…+…+" some_file
sed -e "s'…'…'" some_file
都可以。