我正在尝试编写一个执行以下操作的bash脚本:
1)读取一个文件(f1.txt)的内容
2)对于以“<”开头但不包含“start”或“item”的每一行,在后面的行中插入第二个文件(f2.txt)的全部内容。此更改必须在原始文件f1.txt
中完成例如:
f1.txt:
<start>
<name1>
<item>
stuff
</item>
</name1>
<susan>
<item>
stuff
</item>
</susan>
</start>
f2.txt:
HELLO
WORLD
结果,f1.txt:
<start>
<name1>
HELLO
WORLD
<item>
stuff
</item>
</name1>
<susan>
HELLO
WORLD
<item>
stuff
</item>
</susan>
</start>
我该如何解决这个问题?我应该逐行阅读,还是逐个字符阅读?
答案 0 :(得分:3)
您可以使用此awk命令:
awk 'NR==FNR {if (a) a=a ORS $0; else a=$0; next}
/^ *<[^\/]/ && !/<(start|item)>/ {$0=$0 ORS a}1' f2.txt f1.txt
<start>
<name1>
HELLO
WORLD
<item>
stuff
</item>
</name1>
<susan>
HELLO
WORLD
<item>
stuff
</item>
</susan>
</start>
答案 1 :(得分:1)
你有一个像这样的纯bash脚本解决方案:
#!/bin/bash
readarray -t S < f1.txt
readarray -t R < f2.txt
for A in "${S[@]}"; do
if [[ $A =~ ^([[:blank:]]*)\<([^/].*)\> ]] && [[ ${BASH_REMATCH[2]} != start && ${BASH_REMATCH[2]} != item ]]; then
echo "$A"
for A in ${R[@]}; do
echo "${BASH_REMATCH[1]} $A"
done
else
echo "$A"
fi
done
Runas bash script.sh
。要修改f1.txt
,请修改for
块末尾的最后一行,将输出重定向到它。
done > f1.txt
输出:
<start>
<name1>
HELLO
WORLD
<item>
stuff
</item>
</name1>
<susan>
HELLO
WORLD
<item>
stuff
</item>
</susan>
</start>
如果匹配的深度较高,只要缩进为2个空格,它仍会产生统一的输出。
答案 2 :(得分:1)
仅仅因为您不应该使用sed
,以下是使用sed
的方法。
sed -e '/ *<[^/]/{/\(start\|item\)/!{r f2.txt'$'\n''}}' f1.txt
对不起不客气。