2014-04-22 13 views
1

我有一個看起來像這樣多個文件:Unix的:從文件中抓取日期和排序他們

//file start 
$thing1 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2013-10-01'}; 
$thing2 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2012-11-01'}; 
$thing3 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2014-12-01'}; 
//file end 

使用Unix的,什麼是抓住所有的項目中是日期的文件的最好方法。我知道我在檔案中尋找的物品看起來像是

{somethingDate = '1111-11-11'} 

從這我想搶'1111-11'11'。文件一會有多個'fileOneDate'條目,文件二會有多個'fileTwoDate'條目等等。我的目標是將所有這些日期都是'* Date',刪除重複項,並將它們排序到一個輸出文件中使用sort命令和管道很容易。不過,我被困在第一部分。我到目前爲止是這樣的:

<command I'm working on now that grabs dates> | sort -n > outputfile.txt 

我相信去將是一個AWK腳本的方式。什麼是解析這些文件的正確方法?

回答

1

你需要這樣嗎?

sed -n "s/.*'\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)'.*/\1/p" 

如果您有sed-r選項,

sed -nr "s/.*'([0-9]{4}-[0-9]{2}-[0-9]{2})'.*/\1/p" 

測試:

sat:~# echo "{somethingDate = '1111-11-11'}" | sed -n "s/.*'\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)'.*/\1/p" 
1111-11-11 
sat:~# 
sat:~# echo "$thing1 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2013-10-01'};" | sed -n "s/.*'\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)'.*/\1/p" 
2013-10-01 
+1

如果你使用'r'選項,你不需要逃避'()'這樣的:'sed的-nr「S /.*「([0-9] {4} - [0-9] {2} - [0-9] {2})'。*/\ 1/p「' – Jotne

+0

@Jotne,是的。更新了答案。 – sat

0

如果您的樣本文件被稱爲datefile,則:

$ sed -nr "s/.*Date' => '([^']+)'.*/\1/p" datefile | sort -n 
2012-11-01 
2013-10-01 
2014-12-01 

上述正則表達式查找包含Date' => 'datestring'的行並打印日期字符串。

更詳細地說,sed命令由sed樣式的替換組成,編寫爲s/old/new/optionsold部分有點複雜,所以我會逐一瀏覽:old正則表達式尋找(a).*意味着什麼(任意數量的任何字符),其次是(b)Date' => ',其次是(c)([^']+)是指一個或多個不是單引號的字符,後跟(d)單引號,後面跟(e).*,這也意味着什麼。如果匹配成功,那麼該行被替換爲日期字符串(由於日期字符串正則表達式在parens中而被保存爲\1),然後由於表達式末尾的p而打印該日期。由於-n選項給出sed,因此不會打印沒有匹配的日期字符串的行。

如果您sed不支持-r(OSX),然後用類似的表達,但有一些附加的反斜槓:

sed -n "s/.*Date' => '\([^']\+\)'.*/\1/p" datefile | sort -n 
+0

請注意,Mac OS X'sed'支持擴展正則表達式(而不是'-r')的'-E'。 –

1

grep -o是提取文本的最簡單方法。
sort -u排序(杜)和刪除重複。

grep -oE '\<[0-9]{4}-[0-9]{2}-[0-9]{2}\>' <<'END' | sort -u 
$thing1 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2013-10-01'}; 
$thing2 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2012-11-01'}; 
$thing3 = {'item1' => '0', 'item2 => '3', 'itemDate' => '2014-12-01'}; 
$thing2b= {'item1' => '0', 'item2 => '3', 'itemDate' => '2012-11-01'}; 
$thing2c= {'item1' => '0', 'item2 => '3', 'itemDate' => 'foo2012-01-01bar'}; 
END 
2012-11-01 
2013-10-01 
2014-12-01 
+0

+1爲簡單並保持簡單回答 – SriniV

+0

'-o'選項在GNU'grep'和BSD(Mac OS X)'grep'中可用,但未由POSIX定義。因此,根據Unix平臺,它可能會或可能不可用。 –

+0

感謝您的澄清,喬納森。幸運的是busybox grep有這個選項。 –