- 論壇徽章:
- 0
|
本帖最后由 sosodream 于 2011-05-21 02:57 編輯
閑著無(wú)聊,繼續(xù)答題
問(wèn)題:GNU sed 提供了-i選項(xiàng),為什么有人說(shuō)sed -i 并不象 ed 一樣真正的編輯文件?(提示:觀(guān)察文件改變前后的inode)
注意審題的話(huà),這題是二個(gè)文件編輯器的比較,
也有可能是提示的誤導(dǎo),這題大都知道答-i 是用臨時(shí)文件的機(jī)制,
但這道題如果不通過(guò)說(shuō)明ed 的模式,再做sed -i 與ed 比較,
怎么看都不算完整
======sed的基本模式======
sed的模式是基于二個(gè)space的cycle的“流編輯器”,流的特點(diǎn):有進(jìn)有出,一次一行,不能回退即不能重復(fù)讀
sed -i的編輯模式:將原文件rename成新文件名(tmpfile),以tmpfile為輸入,一行一行處理后,輸出保存到文件(與原文件同名)
======ed===========
ed,這個(gè)以前沒(méi)用過(guò),剛找男人問(wèn)來(lái)的,今天閑著又翻了下源碼看了下
ed的模式就是:scrach_file + line_buffer + command動(dòng)作,
scrach_file是ed一開(kāi)始調(diào)用標(biāo)準(zhǔn)tempfile函數(shù)創(chuàng)建的,tempfile在/tmp下以“程序名.隨機(jī)后綴”為名讀寫(xiě)方式創(chuàng)建一個(gè)臨時(shí)文件,并在程序時(shí)退出時(shí)刪除- [root@rac0 tmp]# file ed.b3db5b
- ed.b3db5b: ASCII text, with no line terminators
復(fù)制代碼 臨時(shí)文件保存的是純數(shù)據(jù)(無(wú)行結(jié)束符),而line_buffer有點(diǎn)像“元數(shù)據(jù)”,是內(nèi)存中的一個(gè)結(jié)構(gòu)鏈表,一個(gè)節(jié)點(diǎn)一個(gè)行信息,保存各行起始位移和長(zhǎng)度
ed file命令下會(huì)在運(yùn)行ed時(shí)一開(kāi)始便將文件全部讀取,數(shù)據(jù)去除換行符后存放到臨時(shí)文件,行信息保存在line_buffer里,然后進(jìn)行相關(guān)操作
ed里的命令w將根據(jù)buffer里的記錄信息將數(shù)據(jù)全部保存回文件
========比較=========
所以sed -i 跟ed是二種不同的文件編輯模式,
從執(zhí)行模式來(lái)區(qū)別:
sed -i是將文件存重命名為臨時(shí)文件后做為輸入流,按行讀取進(jìn)行cycle處理,輸出保存到與原文件同名的新空文件里。
后者是將文件一次全部讀取,然后將數(shù)據(jù)存放到內(nèi)存buffer和臨時(shí)文件里,處理完后再通過(guò)w命令回寫(xiě)入文件
從編輯對(duì)像來(lái)區(qū)別:
sed跟ed的單元?jiǎng)幼鞫际且孕袛?shù)據(jù)為對(duì)象的,也程為行操作。不同在于
sed -i 的處理過(guò)程中,保存在內(nèi)存里二個(gè)buffer的是部分行數(shù)據(jù),可能是一行或多行數(shù)據(jù)
ed 處理過(guò)程中,保存在內(nèi)存里的是所有的行信息。
從inode來(lái)區(qū)別:用inode來(lái)區(qū)分二者的編輯模式,也是一種方法
由于sed把原文件rename了,結(jié)果的文件inode已經(jīng)非原來(lái)的inode了
這種情況下,可以加入sed -c操作,保留文件的inode不變了
-c是gnu sed 提供的,其他unix下的sed冒似不一定有(悲具的unix)
======================
這個(gè)題目出得有點(diǎn)讓人郁悶,什么叫“真正的編輯文件”
真正的編輯文件,比如c程序(不帶緩存的文件I/O)里OPEN文件后,直接根據(jù)描述符,對(duì)文件進(jìn)行讀寫(xiě)
而sed -i 實(shí)際上是流處理,ed在處理過(guò)程中實(shí)際上是在編輯“臨時(shí)文件”
事實(shí)上個(gè)人覺(jué)得sed -i 跟ed都不是“真正的編輯”文件 |
|