2017-07-03 179 views
0

我已经在使用一个脚本来从shell脚本中替换Makefile中的变量“SUBDIRS”的值。 我使用下面的命令,它工作正常,但在第一次发生“SUBDIRS”之后退出并且makefile不完整。如何使用sed替换文件中的多个变量?

sed -z -i "s/\(SUBDIRS = \).*/\1$(tr '\n' ' ' < changed_fe_modules.log)\n/g" Makefile 

现在,我要保持我的Makefile文件,因为它是和只替换出现3次“SUBDIRS = ABCDEFGH”,并正确地更新Makefile文件。

请建议如何替换所有3次出现,并保持Makefile也作为原始结尾。

Makefile中输入样本:

enter image description here

Makefile文件所需的输出样本:

enter image description here

眼下,当前命令是给我下面的输出:它首先更换和文件后退出不完整的。

enter image description here

+0

给Makefile'的'样本的数据和预期的输出。 – Utsav

+0

@Utsav更新我的问题与更多细节。 – user3256114

+0

为什么你想要多次重复相同的SUBDIRS语句?无论你想要做什么在awk中都是微不足道的,但你必须添加简洁,可测试的样本输入和预期输出(即文本,而不是文本照片!)并添加awk标签以获得帮助。 –

回答

0

这将是很难做到的。

您看到此行为的原因是,您在sed中使用了-z选项。 -z选项用NUL字符分隔线条,而不是换行符。这意味着整个文件(直到第一个NUL字符,这里没有一个)被视为一个单一的“行”,用于sed的模式匹配。

所以这个表达式:

\(SUBDIRS = \).* 

.*这里的第一SUBDIRS =比赛后的文件的全部其他部分相匹配。然后用changed_fe_modules.log文件的内容替换整个文件的其余部分。之后没有什么可以匹配的,所以sed完成了。

如果您的原始生成文件在单行中列出了所有的SUBDIRS,而不是使用反斜杠/换行符分隔符,那将很简单;你可以使用:

sed -i "s/^SUBDIRS = .*/SUBDIRS = $(tr '\n' ' ' < changed_fe_modules.log)/" Makefile 

如果你必须使用反斜杠/换行符你可能不会能够使使用SED这种变化。您需要使用更强大的功能,如Perl,它具有非贪婪的匹配功能。

ETA

你也可以把它写在一个简单的shell:

new_subdirs=$(tr '\n' ' ' < changed_fe_modules.log) 
line_cont=false 
in_subdirs=false 

while read -r line; do 
    if $line_cont; then 
     case $line in 
      (*\\) : still continuing ;; 
      (*) line_cont=false ;; 
     esac 
     $in_subdirs || printf '%s\n' "$line" 
     continue 
    fi 

    case $line in 
     (SUBDIRS =*) 
      echo "SUBDIRS = $new_subdirs" 
      in_subdirs=true ;; 
     (*) printf '%s\n' "$line" 
      in_subdirs=false ;; 
    esac 

    case $line in 
     (*\\) line_cont=true ;; 
    esac 

done <Makefile> Makefile.new 

mv -f Makefile.new Makefile 

(注意,经过充分测试)

+0

感谢您的解释。这给了更多的清晰度。我会看看我是否可以在这里使用任何其他语言,因为我的脚本的其余部分是在bash中。 – user3256114