[英]Sed/Awk to search and replace/insert text in files
我正在嘗試更新或插入一些注釋,如版權標題到目錄中的所有源文件(Linux)。 我的文件不一致,因此其中一些文件已經有標題,而其他文件根本沒有標題。 我嘗試用sed
查看前幾行並替換。 替換我的意思是更改已經具有最新版權標題的文件。
sed -e '1,10 s/Copyright/*Copyright*/g' file
但是,如果找不到模式,則不會插入。 我怎樣才能做到這一點?
示例我在評論中提供或我試圖實際替換/插入的是多行典型版權標題,如下所示
/*
* Copyright 1234 XXXNAME, XYZPlace
* text text text text ...........
* blah blah blah */
它也可能包含一些特殊字符。
如果我理解正確,你想:
另外,你想要:
在我看來,這兩個任務可以歸結為一組:
如果我們可以安全地假設您在問題評論中放置的縮小版本的樣本文本是有效的,並且應該插入到每個文件的第2行,那么以下內容應該實現第一組要求你正在使用GNU sed:
find . -type f -not -exec grep -q Copyright {} \; -exec sed -i'' '2i/* Copyright */' {} \;
如果你沒有運行GNU sed(即你在FreeBSD或OSX或Solaris等),請告訴我們,因為sed腳本會有所不同。
這是如何工作的 ?
find
命令獲得以下選項:
-type f
告訴它只查看文件(不是目錄或設備)。 -not
反轉以下選項。 -exec grep -q Copyright {} \\;
將搜索限制為包含版權的任何內容(由-not
修改) -exec sed -i'' '2i/* Copyright */' {} \\;
插入您的版權聲明。 如果您希望您的版權聲明包含可由sed腳本解釋的特殊字符,則此解決方案可能會遇到困難。 但它回答了你的問題。 :)
相反,如果我們想要處理修訂后的要求,即首先刪除現有的版權聲明,那么我們可以用兩個單行來完成:
首先,我們刪除現有的版權聲明。
find . -type f -exec sh -c 'head {} | grep -q Copyright' \; -exec sed -ne '10,$ta;/Copyright/d;:a;p' {} \;
這可能有點多余,除非您想以遞歸方式遍歷子目錄,默認情況下會find
。 sed腳本對前10行中沒有版權信息的文件不執行任何操作,因此如果所有文件都在一個目錄中,則以下內容也應該起作用:
for file in *;do sed -ne '10,$ta;/Copyright/d;:a;p' "$file"; done
接下來,我們重新添加新的。
for file in *;do sed -i'' '2i/* Copyright */' "$file"; done
或者,如果您想通過子目錄遞歸執行此操作:
find . -type f -exec sed -i'' '2i/* Copyright */' {} \;
最終更新 :
在此之后,我不能在這個上花更多的時間。
find . -type f \
-exec sh -c 'head {} | grep -q Copyright' \; \
-exec sed -ne '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */' {} \;
什么 ?
第一個-exec
在文件的前10行中搜索單詞“Copyright”。 就像上面發布的第一個例子一樣。 如果grep找到任何內容,則此條件返回true。
第二個-exec
執行替換。 它將整個文件讀入sed的保持緩沖區。 然后當它到達文件的末尾時,它( g
)考慮保持緩沖區,並且( s
)進行多行替換。
請注意,這可能需要進行一些調整,如果您在文件中的其他位置有注釋,它可能根本不起作用。 我不記得GNU sed是否支持非貪婪的明星。 你可以自己研究一下。
這是我的測試:
$ printf 'one\n/* Copyright blah blah\n *\n */\ntwo\n' | sed -n '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */:g;p;}'
one
/* Copyright 1998-2012 */
two
這不會保留您現有的版權信息,但至少它可以解決多線問題。
編輯:如果您有包含空格的文件名,則下面的命令將不起作用,請參閱第一條注釋。
它肯定可以用sed
來完成,但我想到的第一件事是對存在行的文件進行替換,然后使用類似的東西將標題添加到其余文件中
for f in $(grep -lv 'Copyright' *); do sed -i '1i *Copyright*' $f; done
這將適用於當前文件夾中的所有文件,如果需要遞歸,請使用-r
選項grep
。
PS我建議刪除-i
sed
選項進行測試,只有當你確定命令正常時才添加它。
要在文件的第1行插入包含文本copyright
的單行,只有它不存在,您可以執行以下操作:
sed '1{ /copyright/!i\
copyright
}' input-file
要插入多行:
sed '1{ /copyright/!i\
copyright\
second line
}' input-file
使用r
從文件中讀取版權是很誘人的,但我無法弄清楚如何在第1行之前而不是在第1行之后插入它。例如:
sed '1{ /copyright/! { x; r copyright-file
G}}' input-file
似乎應該這樣做,但版權文件中的文字從第2行開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.