bru*_*lin 5 bash command-line sed
我想在 sed 命令中使用命令行参数,目前我将参数包装在 '' 中。我的命令是:
mycomputer$ sed 's/^\(.\{'$1'\}\)./\1'$2'/' out2.fa 2 A
Run Code Online (Sandbox Code Playgroud)
它本质上查看文件中的一行,并将第二个位置更改为 A。当我对其进行硬编码时,这是有效的,但上面的结果是:
sed: -e expression #1, char 21: Invalid content of \{\}
Run Code Online (Sandbox Code Playgroud)
鉴于文件名在技术上是第一个参数,我还应该使用 $2 和 $3 作为命令行参数吗?
更新:
虽然下一节中的信息(原始答案)一般来说是正确的,但真正的问题是OP错误地认为(位置)参数($1
,...)可以在第一个后脚本sed
(文件名)参数。
然而,脚本参数之后的所有参数sed
实际上都是文件名参数,并且一般没有其他类型的参数或sed
shell变量的概念:
对 shell 变量或参数的任何引用都必须使用预先的字符串扩展(插值)嵌入到脚本中。
通常,arguments $1
, ... 是仅限 shell 的构造,它们引用传递给当前 shell或 shell function内的该函数的参数。
@Qeole的答案提供了一个基于shell函数的解决方案,这是最好的选择。
或者,使用变量:
countBefore=2 newChar='A'
sed 's/^\(.\{'"$countBefore"'\}\)./\1'"$newChar"'/' out2.fa
Run Code Online (Sandbox Code Playgroud)
笔记:
你说changes the 2nd position to an A
。实际上,您的命令有效地替换了第三个字符($countBefore+1
-nth)。)
你说, I am currently wrapping the arguments in ''
。实际上,它是sed
包含在 中的脚本''
,并且您正在拼接 未加引号的参数引用。为了保持鲁棒性,我的基于变量的解决方案将拼接的变量引用加双引号。
拼接变量引用的替代方法是简单地用双引号引用整个sed
脚本并使用嵌入的变量引用:
sed "s/^\(.\{$countBefore\}\)./\1$newChar/" out2.fa
Run Code Online (Sandbox Code Playgroud)
sed: -e expression #1, char 21: Invalid content of \{\}
是 GNUsed
的说法,你指定要进入的内容{...}
($1
) 的内容并不等于有效的重复计数表达式。
换句话说:$1
在您的情况下, 的值不是以下任何一个:
2
),
,可选地后跟另一个十进制数(例如,2,
或2,3
),
,后跟一个十进制数(例如,,3
)确保这$1
是上述之一。
我不确定$1
,$2
\xe2\x80\xa6 等是否可以从命令行访问。
相反,您可以尝试从函数运行您的行。您绝对可以将参数传递给函数。
\n\nfoo() { sed \'s/^\\(.\\{\'"$2"\'\\}\\)./\\1\'"$3"\'/\' "$1"; }\nfoo out2.fa 2 A\n
Run Code Online (Sandbox Code Playgroud)\n\n编辑:正如评论中所建议的,我在参数引用周围添加了双引号,以防止空格破坏命令解析(这应该不是必需的,$2
因为我们只是传递一个整数,但它对于$1
和$3
。