谁能告诉我为什么会这样?我试图在发生给定字符串之前插入一些行,比如说......
thing
extern void hello_dude(char *loc, long length){
thing
到
thing
another
extern void hello_dude(char *loc, long length){
thing
使用一个简单的(叹气)bash 3.0脚本,问题是我使用匹配字符串的if语句是回显像这样拆分的行:
thing
another
extern
void
hello_dude(char
*loc,
long
length){
thing
声明是
elif [[ "$LINE" =~ *hello_dude\(* ]]; then
echo "$LINE" >> temp2
显然,在elif之前工作正常的领先if语句。
我尝试过每一个引用的味道和正则表达式,我可以想象......
任何帮助将不胜感激
编辑:这是使用
的实际脚本#!/bin/bash
for LINE in `(cat temp1)`
do
if [[ "$LINE" = sendMessage4K* ]]; then
echo '/*---RUAISI---*/' >> temp2
echo "$LINE" >> temp2
elif [[ "$LINE" =~ *alpha_display\(* ]]; then
echo "$LINE" >> temp2
echo '/*---RUAISI---*/' >> temp2
else
echo "$LINE" >> temp2
fi
done
temp1文件是:
FIX
sendMessage4K(NomRPC,sbuffer,"KP07");
FIX
extern void alpha_display(char *loc, long length){
FIX
}
FIX
想法是通过以下方式获得temp2:
FIX
/*---RUAISI---*/
sendMessage4K(NomRPC,sbuffer,"KP07");
FIX
extern void alpha_display(char *loc, long length){
/*---RUAISI---*/
FIX
}
FIX
但是我得到了这个
FIX
/*---RUAISI---*/
sendMessage4K(NomRPC,sbuffer,"KP07");
FIX
extern
void
alpha_display(char
/*---RUAISI---*/
*loc,
long
length){
FIX
}
FIX
答案 0 :(得分:1)
如果没有看到您的脚本,我们就无法帮助您。但是,这种问题 - 在特定匹配模式之前插入一行文本 - 通常使用sed
来处理。例如,如果我有一个如下所示的文件:
one
two
three
我想插入" Bananas"在"两个"之前,我会做这样的事情:
sed' / two / i \ Bananas'
这给了我:
one
Bananas
two
three
这假设GNU sed
(虽然它也适用于其他版本的sed的微小修改)。
答案 1 :(得分:1)
您正在使用正则表达式匹配operator =〜,但在其右侧,没有正则表达式,而是shell通配符表达式。所以,将其改为
[[ $LINE == *hello_dude\(* ]]
或
[[ $LINE =~ hello_dude\( ]]
即。使用适当的运算符使用通配符,或使用正确的运算符使用正则表达式。
更新:查看更新后的脚本,我发现问题:您使用的是for
,while
:
#! /bin/bash
while read LINE ; do
if [[ $LINE = sendMessage4K* ]]; then
echo '/*---RUAISI---*/' >> temp2
echo "$LINE" >> temp2
elif [[ $LINE =~ *alpha_display\(* ]]; then
echo "$LINE" >> temp2
echo '/*---RUAISI---*/' >> temp2
else
echo "$LINE" >> temp2
fi
done < temp1
为避免删除前导空格,请在while
:
IFS=$'\n'
答案 2 :(得分:1)
编辑:哎呀,我的回答大多与choroba的那个重复。我要把它留在这里,因为我认为它会更详细地说明事情的原因,但你应该接受choroba的。
你的问题在这里:
for LINE in `(cat temp1)`
这会将每一行拆分为IFS
,因此给定一条输入行:
extern void alpha_display
你得到一个类似于这样的for循环:
for LINE in extern void alpha_display; do
这意味着LINE
按顺序设置为:
为了证明这一点,请尝试以下小脚本:
for LINE in `cat temp1`; do
echo "$LINE"
done
如果你真的想逐行阅读文件,最好在read
循环中使用while
,并在源文件中重定向输入。将以下输出与上一个脚本生成的内容进行比较:
while read LINE; do
echo "$LINE"
done < temp1
考虑到这一点,您可以像这样修复脚本:
while read LINE; do
if [[ "$LINE" = sendMessage4K* ]]; then
echo '/*---RUAISI---*/' >> temp2
elif [[ "$LINE" = *alpha_display\(* ]]; then
echo '/*---RUAISI---*/' >> temp2
fi
echo "$LINE" >> temp2
done < temp1
请注意,除了使用while
循环之外,我还从elif
表达式中删除了正则表达式运算符(因为,正如之前已经指出的那样,您使用的是glob表达式而不是比正则表达式),我已经删除了一些冗余代码。
此脚本生成以下输出:
FIX
/*---RUAISI---*/
sendMessage4K(NomRPC,sbuffer,"KP07");
FIX
extern void alpha_display(char *loc, long length){
/*---RUAISI---*/
FIX
}
FIX
因为read
实际上仍然在IFS上拆分(然后将它们重新组合在一起),所以最终会丢失前导空格或尾随空格。您可以通过在脚本顶部添加以下内容使IFS仅包含行尾来解决此问题:
IFS='\n'
我仍然建议bash
不一定是这项工作的正确工具。 sed
或awk
可能会更有效。这与awk脚本相同:
#!/usr/bin/awk
/sendMessage4K/ || /alpha_display\(/ {
print "/*---RUAISI---*/"
print
next
}
{print}
如果您将其保存在名为“fixit.awk”的文件中,则可以像这样运行:
awk -f fixit.awk < temp1 > temp2