我想删除行开头的双斜杠以取消注释一行代码,例如第一个注释。我的方法适用于很多其他情况,但这次还不够。这是我的文件.sh:
中的一段代码while read line
do
if [[ $line == *"#define asdasd"* ]]
then
local prefix="\\/\\/ "
local new=${line#$prefix}
local sub="s/$line/$new/g"
echo "old line: " $line
echo "new line: " $new
echo $sub
perl -pi -e "$sub" $FILE
exit
fi
done < $FILE
编辑:
我的问题比这段代码更复杂。我想取消注释(删除双斜线)只有一行匹配模式的行,而不一定是第一行。这就是为什么我无法对整个文件进行操作,而是逐行操作的原因。因此,所有“perl on match”解决方案在我的案例中都不起作用。
编辑:
我正按照一些用户的建议编辑我的问题。
makefile
)。在我当前的解决方案中,我收集了头文件中的所有标志,并且我在每次构建时只能逐个启用。这是我的.h文件的一个例子:
#ifndef SYSTEM_H
#define SYSTEM_H
#include <...>
#define BLA 1
#define BLABLA 2
#define BLABLABLA 3
// #define OPT_0 // Options disabled
// #define OPT_1
#define OPT_2 // Option enabled
// #define OPT_...
// #define OPT_...
// #define OPT_N
[...]
#define function(__exp) \
[...]
#endif
正如您所看到的,我不知道启用/禁用了多少选项,还有其他#define
指令。
我正在编写一个脚本,一次启用一个标志并构建项目。每次重命名编译的文件以防止覆盖。我的一个解决方案是基于上面列出的代码,但不幸的是perl指令不会修改.h文件,删除所选行开头的双斜杠。
答案 0 :(得分:3)
Fedorqui's comment是正确的,但你正在做出真正的一餐!
要编辑您感兴趣的行,只需使用Perl:
perl -pi -e 's/^\/\/// if /#define asdasd/' "$FILE"
这将读取您的文件并进行替换以从匹配模式/#define asdasd/
的行的开头删除斜杠。
在这种情况下并不短,但你也可以将这两种模式结合起来,如下所示:
perl -pi -e 's/^\/\/(.*#define asdasd)/\1/' "$FILE"
目前还不清楚是否要求只执行一次替换,但如果是,则可以将命令更改为:
perl -pi -e 's/^\/\/// if /#define asdasd/ && !$n++' "$FILE"
!$n++
仅在第一次评估时才为真,因此只会进行一次替换。
答案 1 :(得分:1)
如果您确实需要逐行处理文件 ,那么如何解决读取和写入<的问题循环中的em>相同文件 ,由@fedorqui在评论中指出(代码使用bash
语法):
while IFS= read -r line; do
if [[ $line == *"#define asdasd"* ]]
then
# ... process "$line" and update "$FILE"
fi
done <<<"$(< "$FILE")"
"$(< $FILE)"
预先读取整个文件 ,然后使用here-string将其传输到while
循环的标准输入。
$FILE
,以防止与环境/特殊shell变量发生冲突。read
命令更健壮:IFS=
表示保留了前导和尾随空格(您可能想要也可能不想要),{{1}确保-r
个实例不被“吃掉”#34; \
。至于循环中的代码:
read
从new=${line#$prefix}
的开头 剥离//
,因为您已经< em>转义 $line
个字符。分配到/
- 改为使用$prefix
。请注意, prefix='//'
或/
中任何未转义的$line
都会破坏您的$new
命令 - 其他字符。也可能导致问题:见下一点。
perl
是构建替换命令的脆弱方式,因为如果sub="s/$line/$new/g"
和/或$line
碰巧包含字符在正则表达式和替换字符串的上下文中具有特殊含义,或者甚至只是分隔符字符串$new
,该命令将行为异常或中断。
/
perl
中使用以下 s///
函数(解释为here]:bash
# SYNOPSIS
# quotePerlRe <text>
quotePerlRe() { sed -e 's/[^^\\$]/[&]/g; s/\^/\\^/g; s/\\/\\\\/g; s/\$/\\$/g; $!a\'$'\n''\\n' <<<"$1" | tr -d '\n'; }
然后您将按如下方式调用它们:
# SYNOPSIS
# quotePerlSubst <text>
quotePerlSubst() {
IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[$/\]/\\&/g; s/\n/\\&/g' <<<"$1")
printf %s "${REPLY%$'\n'}"
}
答案 2 :(得分:0)
你可以像这样使用sed吗
sed -i -e '/#define asdasd/ s,^//,,' $FILE
所以你只会匹配你想要的模式,然后删除双斜杠。