sed +如何在匹配特定行后附加复杂行

sed +如何在匹配特定行后附加复杂行

我们想要在匹配以 – 开头的行后附加 sed ,以下复杂的行number_of_cars_are

more /tmp/orig_file

number_of_cars_are=$number_of_cars_are

我们要添加的行:

numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `

所以我们做了以下事情

sed '/^[[:space:]]*number_of_cars_are =.*/a numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `' /tmp/orig_file > /tmp/new_file

但我们得到以下结果

sed: can't read /g | awk {print: No such file or directory
sed: can't read } | wc -m `: No such file or directory

所以我们也尝试添加反斜杠

sed '/^[[:space:]]*number_of_cars_are =.*/a numbers=` su hdfs -c \"hdfs dfs -ls  $var/*.jar\" |sed s'/\// /g' | awk '{print \$NF}' | wc -m `' /tmp/orig_file > /tmp/new_file

但同样

sed: can't read /g | awk {print: No such file or directory
sed: can't read $NF} | wc -m `: No such file or directory

关于如何添加线条的任何建议

答案1

最好将 Sed 命令放在文件中,以便 shell 不会尝试解释(想要的)附加行的特殊符号。

longline.sed:

/^[[:space:]]*number_of_cars_are=/a\
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\\// /g' | awk '{print $NF}' | wc -m `

请注意,唯一的修改是转义反斜杠,因为 Sed 解释转义字符。

$ sed -f longline.sed newfile
more /tmp/orig_file

number_of_cars_are=$number_of_cars_are
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `

答案2

我们可以heredoc <<在这个场景中充分利用该功能。

repl=$(cat - <<\eof |\
sed -e 's:[\&/]:\\&:g'
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `
eof
)
$ sed \
    -e '/^[[:blank:]]*number_of_cars_are=/G' \
    -e "s/\\n/&$repl/" \
 /tmp/orig_file 

第一步,使用 Heredoc 打印要附加的行并对其进行处理以转义 RHS s/// 字符并将其存储在变量 repl 中。

然后我们将其插入所选行的 s/// rhs 部分。

请注意,此方法非常 Posixly,不需要任何文件。它假设 uniline repl。

答案3

主要问题是单引号字符串不能包含单引号。要在命令行上提供插入的行,您必须打破单引号字符串,添加带引号的单引号,然后继续该字符串。因此,每个单引号将写为 或'\''as '"'"',其中两个侧翼单引号分别结束和开始单引号之前和之后的单引号字符串。

为了避免采取额外的预防措施,您可以提供要作为文本插入到文档中的行。

如同卡西莫多的回答,但使用引用的此处文档,可能直接从命令行:

sed -f /dev/stdin file <<'END_SED'
/^number_of_cars_are/a\
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `
END_SED

由于此处文档被引用(由初始END_SED分隔符周围的单引号表示),因此 shell 不会扩展其中的任何扩展。

sed实用程序使用从其标准输入读取此处文档-f /dev/stdin

相关内容