我要做的是搜索特定模式的大量源文件,并将此模式的另一个表达式置于其中。我正在查找的文件都具有相同的扩展名* .F90。 我的第一步是使用grep并找到包含allocate但未分配的那些文件的所有行,所以我有:
grep –I “ allocate *(” *.F90 | grep –v allocated
我遇到的第一个问题是括号可能前面有一个或多个空格。我可以
allocate(
or allocate (
or allocate (
这就是我在grep命令中需要“*”的原因。 然而,一般规则(除了空格)说,分配后面跟着“(”而不是正在分配的东西。所以我有:
allocate ( array_name ( ....
这些空格也是可选的 所以我想要做的是找到这个字符串,并在其前面加上以下内容:
If( allocated(array_name) ) deallocate(array_name)
并且在下一行之后,我希望得到原始字符串allocate(array( … .
请注意,array_name是一个字母数字字符串,在替换后出现在多个位置。它是被分配的数组的名称。 如果有人能给我一个如何做到这一点的提示,我将非常感激。我被困住了,不知道怎么做。
答案 0 :(得分:2)
我认为您的意思是要将allocate ( array_name )
替换为If( allocated(array_name) ) deallocate(array_name) allocate ( array_name )
。
在GNU或BSD sed中,您可以执行以下操作:
sed -i.bk -e '/allocated/t' \
-e 's/allocate *( *\([A-Za-z0-9_]*\) *)/If( allocated(\1) ) deallocate(\1) &/' \
*.F90
这将搜索并替换* .F90中的匹配行,并跳过allocated
开启的行。原始文件将被称为* .F90.bk。
正如@Anders Johansson所提到的,可能存在其他情况,分配的参数不是字母 - 下划线,那么你可以在搜索和替换之前搜索它:
for i in *.F90; do
echo "$i"
sed -n '/.*allocate *( *\([^ )]*\) *).*/{h; s//\1/; /^[A-Za-z0-9_]*$/t
x; p;}' "$i"
done
(注意t
之后的换行符,BSD sed将t之后的所有内容解释为标签)。在bash中按ctrl + v ctrl + j在命令行上输入换行符。
/a\(b\)c/
找到匹配字符串h
* h *将匹配abc
保留到保留空间s//\1/
* s * ubstitute上一场比赛abc
与第一组b
b
与^[a-z]*$
匹配,则分支到脚本结束x
e * x *更改保留空间abc
图案空间b
p
* p * rint pattern space b
答案 1 :(得分:1)
cat old_file.txt | sed 's/allocate *( *\([a-zA-Z0-9_]*\)/If( allocated(\1) ) deallocate(\1)\
allocate(\1/' > new_file.txt