我正在编写一个bash脚本来修改一个如下所示的文件:
--- usr1 ---
data data data data
data data data data
data data data data
--- usr2 ---
data data data data
data data data data
--- usr3 ---
data data data data
--- endline ---
一个问题是:如何在最后一个用户数据行之后添加下一个用户行--- usrn ---
?
第二个是:如何删除特定的用户数据行(数据行和--- userx ---
),即我想删除usr2及其所有数据集。
它必须适用于bash 2.05 :)我认为它会使用awk或sed,但我不确定。
这里有一点编辑:实际上用户名没有编号。我们不知道用户会想出什么。我们只知道名称将在---
模式
答案 0 :(得分:1)
给出变量中的用户名:
username="kasper"
删除用户部分:
sed "/$username/{:a;N;/\n--- [^[:blank:]]* ---\$/{s/.*\n//;b};ba}" inputfile
或某些版本的sed
(已修改):
sed -e "/$username/{" -e ':a' -e 'N' -e '/\n--- [^[:blank:]]* ---$/{s/.*\n//' -e 'b' -e '}' -e 'ba' -e '}' inputfile
编辑:可能的变体以容纳前导和尾随空格:
sed -e "/$username/{" -e ':a' -e 'N' -e '/\n[[:blank:]]*---[[:blank:]]*[^[:blank:]]*[[:blank:]]*---[[:blank:]]*$/{s/.*\n//' -e 'b' -e '}' -e 'ba' -e '}' inputfile
添加下一个用户部分:
sed "s/--- end/--- $username ---\ndata data data data\ndata data data data\n&/"
或
sed "/--- end/i--- $username ---\ndatadata data data\ndata data data data\n"
如果您的sed
版本支持就地更改,则可以执行以下操作:
sed -i ...
否则,您将不得不使用临时文件:
sed ... inputfile > tmpfile && mv tmpfile inputfile
最好使用mktemp
或tempfile
等实用程序来创建临时文件并使用提供的名称。
答案 1 :(得分:0)
更新了答案以包含第二项要求 ...
#!/bin/sh
NEWUSER='John Doe'
NEWUSERDATA='how now brown cow'
REMOVEUSER='usr2'
state=COPY
while read x; do
case "$state/$x" in
*"/--- endline ---")
echo --- $NEWUSER ---
echo "$NEWUSERDATA"
state=COPY
;;
COPY/*)
if [ "$x" == "--- $REMOVEUSER ---" ]; then
state=REMOVE
fi
;;
REMOVE/---*)
state=COPY
;;
esac
if [ $state != REMOVE ]; then
echo "$x"
fi
done
用法类似于:sh newuser.sh < usertable.txt > newusertable.txt
顺便说一句,还有一种编写shell脚本的替代方式,我称之为“gnu configure”格式。在“替代风格”中,主循环将是:
while read x; do
case "$state/$x" in
*"/--- endline ---")
echo --- $NEWUSER ---
echo "$NEWUSERDATA"
state=COPY;;
COPY/*)
[ "$x" == "--- $REMOVEUSER ---" ] && state=REMOVE;;
REMOVE/---*)
state=COPY;;
esac
[ $state != REMOVE ] && echo "$x"
done
答案 2 :(得分:0)
第二部分的awk解决方案:
awk -v del="usr2" 'match($0,/^--- (.*) ---$/,a) {p = (a[1] != del)} p'
如果头部与要删除的用户匹配,则会关闭p
标志,否则会打印每一行。