我有一个diff
带有前导空格的变量(从文件结果中提取),我想将其插入到文件的特定行中。变量:
add=" public function add($hardware_id = null)"
但是当我插入带有 的行时sed
,它不会打印前导空格:
$ sed "50i$add" file
...
public function add($hardware_id = null)
...
如何保留前导空格?
答案1
要在插入变量时保留前导空格,只需转义一次\
后面有反斜杠的空格插入命令i
,像这样:
$ sed '50i\'"$add" file
public function add($hardware_id = null)
不特定于变量,如果文本按字面插入,则效果相同。
不是 POSIX 指定的行为,它要求在插入的文本之前使用转义文字换行符。
答案2
完成的 posixly 方法是使用语法i\
。但由于我们在双引号的保护下,所以我们避免了反斜杠。并且必须通过转义换行符和反斜杠来确保变量对于此操作是安全的
add=' public function add($hardware_id \= null
)'
#------------------------------
# make variable safe to use
# by escaping backslash n newline
esc_add=$(printf '%s\n' "$add" |
sed -e 's:\\:&&:g;$!s:$:\\:g')
sed -e "
5i\\
$esc_add
" file | nl
1 ABC
2 2 3 4:blockA-1
3 7 9 4:blockA-2
4 1 2 5:blockA-3/
5 public function add($hardware_id \= null
6 )
7 ABC
8 13 11 17:blockB-1
9 2 1 1:blockB-2/
10 ABC
11 7 9 14:blockC-1
12 5 8 2:BlockC-2
13 9 9 9:BlockC-3
14 7 1 2:BlockC-4$
答案3
帮自己一个忙,使用perl
orawk
代替sed
这里来做到这一点:
add=$' anything including \\backslash\\
and newline and even non\x80-text or overlong lines '
ADD=$add perl -pe '$_ = "$ENV{ADD}\n$_" if $. == 5' < "$file"
或者(尽管这可能会因内容中的行过长或 NUL 字节而失败,并且要注意,如果最初没有换行符,它会添加尾随换行符):
ADD=$add LC_ALL=C awk 'NR == 5 {$0 = ENVIRON["ADD"] ORS $0}; 1' < "$file"