mycomputer$ sed 's/^\(.\{'$1'\}\)./\1'$2'/' out2.fa 2 A
这个功能主要是查看文件中的一行,并将第二个位置更改为 A。当我在代码中直接设置时,它可以正常工作,但是上述代码会导致:
sed: -e expression #1, char 21: Invalid content of \{\}
我应该使用$2和$3作为命令行参数吗?因为从技术上讲,文件名是第一个参数。
mycomputer$ sed 's/^\(.\{'$1'\}\)./\1'$2'/' out2.fa 2 A
这个功能主要是查看文件中的一行,并将第二个位置更改为 A。当我在代码中直接设置时,它可以正常工作,但是上述代码会导致:
sed: -e expression #1, char 21: Invalid content of \{\}
我应该使用$2和$3作为命令行参数吗?因为从技术上讲,文件名是第一个参数。
更新:
虽然下一节(原始答案)中的信息通常是正确的,但真正的问题在于OP错误地认为(位置)参数($1
,...)可以在第一个后脚本(文件名)参数之后传递给sed
的参数。
然而,实际上,在sed
的脚本参数之后的所有参数都是文件名参数,并且sed
没有关于其他类型的参数或shell变量的概念:
任何对shell变量或参数的引用必须嵌入到脚本中,使用前置字符串扩展(插值)。
通常,参数$1
,...是仅限于shell的构造,用于引用传递给当前shell或在shell 函数内部的该函数的参数。
@Qeole's answer 提供了一个基于 shell 函数 的解决方案,这是最佳选择。
或者,可以使用 变量:
countBefore=2 newChar='A'
sed 's/^\(.\{'"$countBefore"'\}\)./\1'"$newChar"'/' out2.fa
你说“将第二个位置改为A”。实际上,你的命令实际上是替换了第三个字符($countBefore+1-nth)。
你说,“我目前正在用''包裹参数”。实际上,是sed脚本被包裹在''中,而你是插入了未引用的参数引用。我的基于变量的解决方案对插入的变量引用进行了双引号处理,以确保稳健性。
替代插入变量引用的方法是简单地对整个sed脚本进行双引号处理并使用嵌入的变量引用:
sed "s/^\(.\{$countBefore\}\)./\1$newChar/" out2.fa
sed: -e expression #1, char 21: Invalid content of \{\}
是GNU sed
的方式,表示你指定放在{...}
中的内容($1
)不构成有效的重复计数表达式。
换句话说:在你的情况下,$1
的值不是以下任何一种:
2
),
,可选地再跟着另一个十进制数(例如:2,
或2,3
),
后面跟着一个十进制数(例如:,3
)确保$1
是以上三种情况之一。
我不确定从命令行可以访问$1
,$2
等变量。
相反,您可以尝试从函数中运行代码。您肯定可以将参数传递给函数。
foo() { sed 's/^\(.\{'"$2"'\}\)./\1'"$3"'/' "$1"; }
foo out2.fa 2 A
编辑:如评论中所建议,我在参数引用周围添加了双引号以防止空格破坏命令解析(对于$2
来说不需要这样做,因为我们只传递一个整数,但对于$1
和$3
来说更好)。