將一些內容附加到文件中的每個列表
我有一個文件,lists.txt,看起來像這樣:
// stuff at beginning of file var list1 = new Array(); i = 0; list1[i++] = 'a'; list1[i++] = 'b'; ... list1[i++] = 'z'; var list2 = new Array(); i = 0; list2[i++] = 'a'; list2[i++] = 'b'; ... list2[i++] = 'z'; // other stuff at end of file
我需要附加到這些列表中的每一個(其中有兩個以上)並最終得到如下內容:
var list1 = new Array(); i = 0; list1[i++] = 'a'; list1[i++] = 'b'; ... list1[i++] = 'z'; list1[i++] = 'something new'; var list2 = new Array(); i = 0; list2[i++] = 'a'; list2[i++] = 'b'; ... list2[i++] = 'z'; list2[i++] = 'another thing'; // other stuff at end of file
我一直在為此絞盡腦汁。我知道如何獲取每個列表的最後一次出現:
list1_last=$(grep "list1\[i++\]" lists.txt | tail -1) list2_last=$(grep "list2\[i++\]" lists.txt | tail -1)
我知道如何在第一個列表的開頭和第二個列表的開頭(包括)之間獲取所有內容:
list1=$(sed -n '/var list1/,/var list2/p' lists.txt)
我知道我可以在沒有 list2 的第一行的情況下使用這個 Perl one-liner或這個瘋狂的 sed script來獲得 list1 。
但是我很難把所有的部分放在一起。我該怎麼做?
編輯
我要附加的附加值在另一個文件 additional-values.txt 中,例如包含:
list1[i++] = 'something new'; list2[i++] = 'another thing';
我想你可以說我正在嘗試合併這兩個文件。
編輯 2
實際文件看起來更像這樣:
// comment // comment // ... var foo = "bar"; // comment // comment // ... var i= 0; // comment // comment // ... var GoodDomains = new Array(); i=0; GoodDomains[i++] = "anything.com"; // comment GoodDomains[i++] = "something.com"; // comment ... GoodDomains[i++] = "lastthing.com"; // comment // THIS IS WHERE I WANT TO INSERT SOMETHING // comment // comment // ... var BadDomains = new Array(); i=0; BadDomains[i++] = "anything.com"; // comment BadDomains[i++] = "something.com"; // comment ... BadDomains[i++] = "lastthing.com"; // comment // THIS IS WHERE I WANT TO INSERT SOMETHING // more lists, including GoodHosts, GoodURLs, etc. // comment // comment // ... for (i in GoodDomains) { ... } // loop through BadDomains, GoodHosts, GoodURLs, etc. // comment // comment // ... function IsNumIpAddr(host) { ... }
我最初發布了一個簡化版本,因為
- 我不確定實際文件是否總是遵循這種格式(頂部的註釋、變數聲明、更多註釋、列表定義、函式等)
- 我想找到該問題的通用解決方案(將內容附加到文件中間的列表中)
抱歉,如果這具有誤導性。
由於您正在嘗試使用
sed
範圍,因此這是一種可能的方法。您的行additional-values.txt
遵循相同的模式:KEY[i++] = 'VALUE'; //etc
據我所知,每一行都應該插入一個總是由
var KEY = new Array();
和一個空行
因此您可以處理
additional-values.txt
並將其轉換為sed
對每一行執行的腳本:/^var KEY = new Array();/,/^$/{ /^$/ i\ KEY[i++] = 'VALUE'; // etc }
也就是說,在
/^var KEY = new Array();/,/^$/
範圍內,KEY[i++] = 'VALUE'; // etc
在空行之前插入一行。然後,您使用腳本來處理lists.txt
:sed 's/\\/&&/g' additional-values.txt | \ sed 's|^\([^[]*\).*|/^var \1 = new Array();/,/^$/{\ /^$/ i\\\ &\ }|' | sed -f - lists.txt
第一個
sed
轉義任何反斜杠,第二個sed
處理將其轉換為第三個(通過)用於處理additional-values.txt
的腳本。 例如樣本內容:sed``-f``lists.txt
additional-values.txt
GoodDomains[i++] = '^stuff/here/'; \ BadDomains[i++] = '%XYZ+=?\\<>'; GoodNetworks[i++] = '|*{};:\'; // Malware\\ BadDomains[i++] = '\$.|&$@"#"!||';
的結果:
sed 's/\\/&&/g' additional-values.txt | \ sed 's|^\([^[]*\).*|/^var \1 = new Array();/,/^$/{\ /^$/ i\\\ &\ }|'
是
/^var GoodDomains = new Array();/,/^$/{ /^$/ i\ GoodDomains[i++] = '^stuff/here/'; \\ } /^var BadDomains = new Array();/,/^$/{ /^$/ i\ BadDomains[i++] = '%XYZ+=?\\\\<>'; } /^var GoodNetworks = new Array();/,/^$/{ /^$/ i\ GoodNetworks[i++] = '|*{};:\\'; // Malware\\\\ } /^var BadDomains = new Array();/,/^$/{ /^$/ i\ BadDomains[i++] = '\\$.|&$@"#"!||'; }
然後將其傳遞給
sed -f - lists.txt
so ,例如 samplelists.txt
:// Counter Variable to initalize the arrays. var i= 0; var GoodDomains = new Array(); i=0; GoodDomains[i++] = 'aba.com'; // Phish - 2010-02-05 var GoodNetworks = new Array(); i=0; GoodNetworks[i++] = '10.0.0.0, 255.0.0.0'; // NRIP // GoodNetworks[i++] = "63.140.35.160"; // DNSWCD 2o7 var BadDomains = new Array(); i=0; BadDomains[i++] = '.0catch.com'; // AdServer - 2009-06-16 //var BadDomains = new Array();
跑步:
sed 's/\\/&&/g' additional-values.txt | \ sed 's|^\([^[]*\).*|/^var \1 = new Array();/,/^$/{\ /^$/ i\\\ &\ }|' | sed -f - lists.txt
輸出:
// Counter Variable to initalize the arrays. var i= 0; var GoodDomains = new Array(); i=0; GoodDomains[i++] = 'aba.com'; // Phish - 2010-02-05 GoodDomains[i++] = '^stuff/here/'; \ var GoodNetworks = new Array(); i=0; GoodNetworks[i++] = '10.0.0.0, 255.0.0.0'; // NRIP // GoodNetworks[i++] = "63.140.35.160"; // DNSWCD 2o7 GoodNetworks[i++] = '|*{};:\'; // Malware\\ var BadDomains = new Array(); i=0; BadDomains[i++] = '.0catch.com'; // AdServer - 2009-06-16 BadDomains[i++] = '%XYZ+=?\\<>'; BadDomains[i++] = '\$.|&$@"#"!||'; //var BadDomains = new Array();
如果您喜歡
gnu sed
並處理替換:sed -E 's|^([^[]*).*|/^var \1 = new Array();/,/^$/{/^$/ i\\\n&\ }|' <(sed 's/\\/&&/g' additional-values.txt) | sed -f - lists.txt
如果您反轉文件,您可以在第一次看到某些內容時添加一行:
tac lists.txt | awk -v l1="list1" -v val1="something new" \ -v l2="list2" -v val2="another thing" ' index($0, l1"[i++]") && !found1 { printf "%s[i++] = \"%s\";\n", l1, val1 found1 = 1 } index($0, l2"[i++]") && !found2 { printf "%s[i++] = \"%s\";\n", l2, val2 found2 = 1 } {print} ' | tac > lists.txt.new
它有點不干,但它會做。
我錯過了“additional-values.txt”。這樣更好:
tac lists.txt | awk ' NR == FNR {additional[$1] = $0; next} $1 in additional && !found[$1] {print additional[$1]; found[$1] = 1} {print} ' additional-values.txt - | tac > newfile