sed - 变量作为行位置

sed - 变量作为行位置

我尝试使用变量(行位置)作为“剪切”文件的参数,但我在 sed 命令中遇到错误。

这是我的代码:

START=$(grep -n "pattern1" $FILE | cut -f1 | sed 's/:.*$//g')
END=$(grep -n "pattern2" $FILE | cut -f1 | sed 's/:.*$//g')
sed -n '${START},${END}p' $FILE > temp; # error here
# sed: -e expression #1, char 3: unknown command: `S'

但当我使用数字时它会起作用:

sed -n '28,63p' $FILE > temp;

看来是需要申请一些逃生,但我无法解决。有什么建议吗?非常感谢!

答案1

您的代码的主要问题是您期望 shell在单引号字符串中扩展您的START和变量。 ENDshell 永远不会这样做,这是单引号字符串和双引号字符串之间的主要区别之一。

相反,请在表达式中使用双引号字符串sed

然而,您似乎还期望您的两个grep管道分别返回一个行号,在这种情况下,我看不到它们的原因,因为您可以sed直接执行此表单。sed如果命令采用多个地址,则命令采用行号、正则表达式或这些形式的组合形式的地址。

sed -n '/pattern1/,/pattern2/ p' "$FILE" >temp

或者

sed '/pattern1/,/pattern2/ !d' "$FILE" >temp

您可能不应该保留grep管道,但这是为了补充一点,您可以将它们缩短为直接返回行号的东西sed

start=$( sed -n '/pattern1/ { =; q; }' )

上面将为您提供与模式匹配的第一行的行号pattern1。它是=输出当前行号的命令。

答案2

正如所讨论的,需要更改为双引号,但是如果文件具有超过一倍的模式,则原始脚本也会被破坏。上面的解决方案效果很好,只需打印开始/结束模式之间的每一行即可。此单行代码仅打印第一次出现的情况:

    sed -n '/pattern1/{:loop;p;/pattern2/q;N;s/.*\n//;b loop};' "$file"

相关内容