Shell-Script
如果文件中不存在這些行,如何將多行附加到文件中?
如果文件中不存在這些行,如何將多行附加到文件中?
例如,要添加多個全域別名,
/etc/bash.bashrc
我使用heredocument:cat <<-"BASHRC" >> /etc/bash.bashrc alias rss="/etc/init.d/php*-fpm restart && systemctl restart nginx.service" alias brc="nano /etc/bash.bashrc" BASHRC
我被批評說這個操作不包括檢查行是否已經存在的方法,如果錯誤地重新執行 heredocument,我可能會導致冗餘以及沖突。
用於將文件中的行添加
newdata
到datafile
. 更改newdata
為 here-doc 應該很簡單。這實際上不是很有效,因為它需要grep
每個(新)輸入行:target=datafile while IFS= read -r line ; do if ! grep -Fqxe "$line" "$target" ; then printf "%s\n" "$line" >> "$target" fi done < newdata
對於每一行,我們使用
grep
它來查看它是否已經存在於目標文件中,-F
用於固定字元串匹配(無正則表達式),-x
用於全行匹配,並-q
抑制匹配行的輸出。grep
如果沒有找到匹配的行,則返回虛假錯誤程式碼,因此如果否定結果為真,則附加到目標文件。更有效地,在
awk
. 這依賴於awk
能夠將任意行作為數組的鍵來處理。$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata
第一部分
FNR == NR { lines[$0] = 1; next }
將第一個輸入文件的所有行作為鍵載入到(關聯)數組lines
中。第二部分! ($0 in lines) {print}
在以下輸入行上執行,如果該行不在數組中,則列印該行,即“新”行。結果輸出僅包含新行,因此需要將其附加到原始文件中,例如
sponge
:$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata | sponge -a datafile
或者我們可以
awk
將這些行附加到最後一行,它只需要將文件名傳遞給awk
:$ target=datafile $ awk -vtarget="$target" 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print >> target}' "$target" newdata
要將 here-doc 與 一起使用,除了設置重定向之外
awk
,我們還需要將(stdin) 添加為顯式源文件,因此-``awk ... "$target" - <<EOF