<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cholwich's blog &#187; text processing</title>
	<atom:link href="http://cholwich.org/wordpress/tag/text-processing/feed/" rel="self" type="application/rss+xml" />
	<link>http://cholwich.org/wordpress</link>
	<description>Just another blog of mine</description>
	<lastBuildDate>Thu, 02 Jun 2011 02:00:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>AWK</title>
		<link>http://cholwich.org/wordpress/2008/07/05/awk/</link>
		<comments>http://cholwich.org/wordpress/2008/07/05/awk/#comments</comments>
		<pubDate>Sat, 05 Jul 2008 05:17:47 +0000</pubDate>
		<dc:creator>cholwich</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[text processing]]></category>

		<guid isPermaLink="false">http://cholwich.org/wordpress/?p=70</guid>
		<description><![CDATA[ตอนนี้พยายามเขียนเรื่องให้มีสาระมากขึ้น มากกว่าแค่แปะลิงก์ แล้วก็กล่าวถึงนิดๆ เพราะลองดูสถิติจาก Google Analytics แล้ว รู้สึกว่ามีคนหลงมาที่นี่เพราะคำสำคัญต่างๆ ที่ใส่ไว้ เห็นมีคนตามมาอ่านเรื่อง fpdf ที่บ่นๆ ไว้ ไม่ค่อยมีสาระเท่าไหร่ คนอ่านคงจะเซ็งว่าไอ้บ้านี่เขียนอะไรไม่มีประโยชน์เลย awk เป็นเครื่องมือที่ช่วยจัดการไฟล์ข้อความ โดยมองว่าข้อมูลในไฟล์แบ่งเป็นเรคอร์ดและฟิลด์ สามารถระบุได้ว่าจะให้ใช้เครื่องหมายอะไรตัวแบ่งระหว่างฟิลด์หรือเรคอร์ด ลองดูตัวอย่างง่ายๆ กันก่อน ถ้าผมมีไฟล์ข้อมูลคะแนนนักเรียนอยู่ แบ่งเรคอร์ดตามบรรทัด และแบ่งฟิลด์ด้วยแท็บ 4822111111 10 4822222222 13 4833333333 14 4844444444 9 ถ้าจะแปลงข้อมูลในไฟล์นี้เป็นตารางในแบบ html ก็ทำได้โดยอ่านไฟล์มาทีละบรรทัด แล้วเพิ่มแท็ก tr และ td ลงไป BEGIN &#123; FS=&#34;\t&#34; print &#34;&#60;table&#62;&#34; &#125; &#160; &#123; print &#34;&#60;tr&#62;&#60;td&#62;&#34;$1&#34;&#60;/td&#62;&#60;td&#62;&#34;$2&#34;&#60;/td&#62;&#60;/tr&#62;&#34; &#125; &#160; END &#123; print [...]]]></description>
			<content:encoded><![CDATA[<p>ตอนนี้พยายามเขียนเรื่องให้มีสาระมากขึ้น มากกว่าแค่แปะลิงก์ แล้วก็กล่าวถึงนิดๆ เพราะลองดูสถิติจาก Google Analytics แล้ว รู้สึกว่ามีคนหลงมาที่นี่เพราะคำสำคัญต่างๆ ที่ใส่ไว้ เห็นมีคนตามมาอ่านเรื่อง fpdf ที่บ่นๆ ไว้ ไม่ค่อยมีสาระเท่าไหร่ คนอ่านคงจะเซ็งว่าไอ้บ้านี่เขียนอะไรไม่มีประโยชน์เลย</p>
<p>awk เป็นเครื่องมือที่ช่วยจัดการไฟล์ข้อความ โดยมองว่าข้อมูลในไฟล์แบ่งเป็นเรคอร์ดและฟิลด์ สามารถระบุได้ว่าจะให้ใช้เครื่องหมายอะไรตัวแบ่งระหว่างฟิลด์หรือเรคอร์ด ลองดูตัวอย่างง่ายๆ กันก่อน ถ้าผมมีไฟล์ข้อมูลคะแนนนักเรียนอยู่ แบ่งเรคอร์ดตามบรรทัด และแบ่งฟิลด์ด้วยแท็บ</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">4822111111	10
4822222222	13
4833333333	14
4844444444	9</pre></div></div>

<p>ถ้าจะแปลงข้อมูลในไฟล์นี้เป็นตารางในแบบ html ก็ทำได้โดยอ่านไฟล์มาทีละบรรทัด แล้วเพิ่มแท็ก tr และ td ลงไป</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">BEGIN <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #007800;">FS</span>=<span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span>
  print <span style="color: #ff0000;">&quot;&lt;table&gt;&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
  print <span style="color: #ff0000;">&quot;&lt;tr&gt;&lt;td&gt;&quot;</span><span style="color: #007800;">$1</span><span style="color: #ff0000;">&quot;&lt;/td&gt;&lt;td&gt;&quot;</span><span style="color: #007800;">$2</span><span style="color: #ff0000;">&quot;&lt;/td&gt;&lt;/tr&gt;&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
END <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  print <span style="color: #ff0000;">&quot;&lt;/table&gt;&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>เมื่อเขียนเสร็จ ก็ลองเอามาใช้งานได้โดย</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ awk -f [awk-file] &amp;lt; [data-file]</pre></div></div>

<p>จะได้ผลเป็นตารางในตามข้างล่าง</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;table border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;4822111111&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4822222222&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4833333333&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4844444444&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</pre></div></div>

<p>ในโปรแกรม awk ข้างต้น แบ่งออกเป็น 3 ส่วน แต่ละส่วนแบ่งด้วยวงเล็บปีกกา ส่วนแรกมีคำว่า BEGIN กำหนดอยู่หมายความว่าให้ทำครั้งเดียวตอนเริ่มต้นอ่านไฟล์ ในที่นี้กำหนดให้ใช้แท็บเป็นตัวแบ่งฟิลด์ แล้วก็พิมพ์ &#8220;&lt;table&gt;&#8221; ออกมา</p>
<p>ส่วนที่สองไม่ได้กำหนดอะไรไว้ก่อนเครื่องหมายวงเล็บปีกกาเปิด ก็จะทำงานทุกครั้งเมื่อขึ้นเรคอร์ดใหม่ จึงเป็นการพิมพ์ข้อมูลทีละแถวในตาราง โดย $1 ใช้แทนข้อมูลในฟิลด์ที่ 1 และ $2 จะแทนฟิลด์ที่ 2  ไปเรื่อยๆ</p>
<p>ส่วนที่สามเริ่มต้นด้วย END จะทำงานเพียงครั้งเดียวเมื่ออ่านไฟล์ทั้งหมดเสร็จแล้ว ดังนั้นจึงแค่พิมพ์ &#8220;&lt;/table&gt;&#8221; ออกมาในตอนท้าย</p>
<p>ด้วยลักษณะที่ awk ทำงานตามเรคอร์ดและฟิลด์ ทำให้การเขียนโปรแกรมเพื่อจัดการกับข้อมูลต่างๆ ทำได้สะดวกขึ้น ไม่จำเป็นต้องเขียนลูปเพื่อวนรอบ แค่เขียนเป็นกฎไว้เท่านั้นก็พอ นอกจากนี้ยังสามารถระบุให้ทำงานกับเรคอร์ดที่แตกต่างกันได้ด้วย โดยใช้ Regular Expression กำหนดรูปแบบของเรคอร์ดนั้น เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>^<span style="color: #000000;">4822</span><span style="color: #000000; font-weight: bold;">/</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> print <span style="color: #ff0000;">&quot;48&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>กฎข้างต้นจะทำให้พิมพ์คำว่า &#8220;48&#8243; เมื่อเรคอร์ดขึ้นต้นด้วย &#8220;4822&#8243; ตามที่กำหนดไว้ใน RE เท่านั้น</p>
<p>จริงๆ แล้วโปรแกรมข้างต้นผมเขียนขึ้นมาใช้งานจริง เวลาจะเอาคะแนนของนักเรียนไปประกาศบนเว็บ หลายคนอาจจะสงสัยว่าทำไมไม่ใช้โปรแกรมพวกสเปรดชีท ทำไมต้องมาใช้ awk ให้เสียเวลา คำตอบก็คือ ผมไม่เคยสามารถทำให้โปรแกรมสเปรดชีทต่างๆ สร้างตารางในรูปแบบ html ที่สะอาดๆ ได้เลย ลองมาหลายโปรแกรมแล้ว ทุกๆ อันจะต้องแทรกโน้นนี่มาให้ตลอด แล้วผมก็เป็นพวกโรคจิต ถ้าเห็นโค้ดที่ไม่สะอาดรกรุงรัง ก็จะต้องพยายามหาทางทำให้สะอาด เนื่องจากอยากให้ตารางมันแสดงไปตามรูปแบบที่เรากำหนดไว้แล้ว สุดท้ายเลยตัดสินใจใช้ awk ดีกว่าสร้างโค้ดได้สะอาดสมใจ</p>
<p>แต่ว่าโปรแกรมข้างต้นก็ยังมีข้อจำกัดอยู่ที่กำหนดจำนวนฟิลด์ไว้ตายตัว ทำให้ไม่ยืดหยุ่นเท่าไหร่ ถ้ามีคะแนนหลายๆ ค่า แต่เนื่องจาก awk นั้นมี control structure อยู่หลายแบบ จึงสามารถเขียนให้ยืดหยุ่นขึ้นได้อีกเป็น</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">BEGIN <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #007800;">FS</span>=<span style="color: #ff0000;">&quot; &quot;</span>
  <span style="color: #007800;">ORS</span>=<span style="color: #ff0000;">&quot;&quot;</span>
  print <span style="color: #ff0000;">&quot;&lt;table class=<span style="color: #000099; font-weight: bold;">\&quot;</span>attendance<span style="color: #000099; font-weight: bold;">\&quot;</span> border=<span style="color: #000099; font-weight: bold;">\&quot;</span>0<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
  print <span style="color: #ff0000;">&quot;&lt;tr&gt;&quot;</span>
  <span style="color: #000000; font-weight: bold;">for</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">i</span>=<span style="color: #000000;">1</span>; i<span style="color: #000000; font-weight: bold;">&amp;</span>lt;=NF; i++<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    print <span style="color: #ff0000;">&quot;&lt;td&gt;&quot;</span><span style="color: #007800;">$i</span><span style="color: #ff0000;">&quot;&lt;/td&gt;&quot;</span>
  print <span style="color: #ff0000;">&quot;&lt;/tr&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
END <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  print <span style="color: #ff0000;">&quot;&lt;/table&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>NF เป็นตัวแปรระบุจำนวนฟิลด์ ซึ่งทำให้เราสามารถใช้ลูปเพื่อพิมพ์ข้อมูลจากทุกๆ ฟิลด์ได้</p>
]]></content:encoded>
			<wfw:commentRss>http://cholwich.org/wordpress/2008/07/05/awk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

