2017-07-03 51 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