我有一个多行字符串,从网上下载:
toast the lemonade
blend with the lemonade
add one tablespoon of the lemonade
grill the spring onions
add the lemonade
add the raisins to the saucepan
rinse the horseradish sauce
我已将此分配给$INPUT
,如下所示:
INPUT=$(lynx --dump 'http://example.net/recipes' \
| python -m json.tool \
| awk '/steps/,/]/' \
| egrep -v "steps|]" \
| sed 's/[",]\|^ *//g; $d')
此时,$INPUT
已准备好替换到我的目标文件中,如下所示:
sed -i "0,/OLDINPUT/s//$INPUT/" /home/test_file
当然,sed抱怨未命令的s
命令 - 这就是问题所在。
我使用的当前解决方法是在将其提供给sed之前echo $INPUT
,但之后不会保留换行符。 echo
删除换行符 - 这就是问题所在。
正确的输出应保持其换行符。如何指示sed保留换行符?
答案 0 :(得分:3)
hacky直接回答是用\n
替换所有换行符,您可以通过添加
| sed ':a $!{N; ba}; s/\n/\\n/g'
到上面的长命令。一个更好的答案,因为将shell变量替换为代码总是一个坏主意,而且你不能选择sed,而是使用awk:
awk -i inplace -v input="$INPUT" 'NR == 1, /OLDINPUT/ { sub(/OLDINPUT/, input) } 1' /home/test_file
这需要-i inplace
的GNU awk 4.1.0或更高版本。
答案 1 :(得分:2)
要清理一些代码。
此:
lynx --dump 'http://somesite.net/recipes' | python -m json.tool | awk '/steps/,/]/' | egrep -v "steps|]" | sed 's/"//g' |sed 's/,//g' | sed 's/^ *//g' | sed '$d'
可以替换为:
lynx --dump 'http://somesite.net/recipes' | python -m json.tool | awk '/]/ {f=0} f {if (c--) print line} /steps/{f=1} {gsub(/[",]|^ */,"");line=$0}'
它可能会缩短更多,但我现在不会这样做:python -m json.tool
此:
awk '/]/ {f=0} f {if (c--) print line} /steps/{f=1} {gsub(/[",]|^ */,"");line=$0}'
的作用:
steps
后面的行打印到]
之前的行 - awk '/steps/,/]/' | egrep -v "steps|]"
"
,,
以及所有行前面的所有空格。 - sed 's/"//g' |sed 's/,//g' | sed 's/^ *//g'
sed '$d'
示例:
cat file
my data
steps data
more
do not delet this
hei "you" , more data
extra line
here is end ]
this is good
awk '/]/ {f=0} f {if (c--) print line} /steps/{f=1} {gsub(/[",]|^ */,"");line=$0}' file
more
do not delet this
hei you more data
答案 2 :(得分:2)
您希望使用编辑器代替sed的替换:
$ input="toast the lemonade
blend with the lemonade
add one tablespoon of the lemonade
grill the spring onions
add the lemonade
add the raisins to the saucepan
rinse the horseradish sauce"
$ seq 10 > file
$ ed file <<END
1,/5/d
1i
$input
.
w
q
END
$ cat file
toast the lemonade
blend with the lemonade
add one tablespoon of the lemonade
grill the spring onions
add the lemonade
add the raisins to the saucepan
rinse the horseradish sauce
6
7
8
9
10
答案 3 :(得分:2)
假设您输入的JSON片段如下所示:
{ "other": "random stuff",
"steps": [
"toast the lemonade",
"blend with the lemonade",
"add one tablespoon of the lemonade",
"grill the spring onions",
"add the lemonade",
"add the raisins to the saucepan",
"rinse the horseradish sauce"
],
"still": "yet more stuff" }
您只能使用
提取steps
成员
jq -r .steps
要将其插入到sed
语句中,您需要在结果中转义任何正则表达式元字符。一个不那么令人生畏和希望稍微不那么讨厌的解决方案就是从标准输入中读取静态文本:
lynx ... | jq ... |
sed -i -e '/OLDINPUT/{s///; r /dev/stdin' -e '}' /home/test_file
教育从业者使用结构感知工具进行结构化数据的斗争已达到epic的高度并且一直没有减弱。在您决定使用快速和肮脏的方法之前,至少要确保您了解危险(技术和心理)。
答案 4 :(得分:2)
如果您正在使用Bash,则可以将\n
替换为换行符:
INPUT="${INPUT//
/\\n}"
如果您不喜欢参数扩展中的文字换行,您可能更喜欢
INPUT="${INPUT//$'\n'/\\n}"
旁注 - 你可能意味着c
将匹配的行改为输入,而不是s
ubstitute。在这种情况下,毕竟你不想引用新行...