PIXNET Logo登入

Jemmy Walker

跳到主文

部落格全站分類:不設分類

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 11月 01 週一 201020:55
  • 無法在crontab執行Perl的system函數之解

  在Perl裡透過systtem或用雙倒引號(`)執行外部程式可以。但使用crontab卻不行,前提確認了權限已足,經Google大師開示,要先執行profile。 下command:crontab -e進入vi編輯: # 分 時 日 週 月 命令 00 21 * * * (. /oracle/.profile; /home/ogg/launcher.pl) 也學到原來crontab的命令不一定只限一行,也可以用小括號括起,用分號隔成數道命令。   然而,system或雙倒引號括起的java程式,如:nohup run.sh &。run.sh內容是java –jar my.jar,卻無法Run成功,原因還是和profile有關。只需在run.sh做以下編輯: JAVA_HOME=/usr/java5
CLASSPATH=.:./lib
export JAVA_HOME CLASSPATH
java -jar -cp $CLASSPATH -Xms1G -Xmx4G /home/jemmy/my.jar
  不只宣告JAVA_HOME和CLASSPATH環境變數,要被crontab執行,其jar檔還要附上絕對路徑。此外,若程式裡有遇到需要讀相對路徑的配置檔,也就不能像Spring一樣在ClassPath被搜尋到,又該如何?   以本例來看,是用oracle這個user登入(. /oracle/.profile),也表示相對路徑之基準路徑為/oracle,而my.jar程式可以透過如下方式取得該jar絕對路徑: String classPath = MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 其classPath會是/home/jemmy/my.jar。是故剔掉my.jar即絕對路徑:classPath.replaceAll("[^/]+\\.jar$", "");
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(318)

  • 個人分類:Regex
▲top
  • 10月 13 週三 201021:19
  • Perl的跨行比對

  這案子後期用Perl機會難得的多,就出個Java的跨行比對的Perl版。第一步,Java將javaue.def檔案內容轉成一個String,Perl如法泡製更簡單,因為不太用,不得其法:   一般是@lines = <F>;來將檔案內容全存進陣列變數,若是$line = <F>則只存第一列。而想$line涵蓋檔案內容,必須先執行undef $/;才行。$/是換行變數,預設是\n,可以改變它為其它字符,而undef它表示使用鑽石符號<>不必分列讀進,一口氣英文…不,一口氣讀進變數。   第二,比對出多個符合pattern,我竟沒Java熟,但真的有比Java簡單,一直以為是帶gm參數,g是全域,m是多列,但真正的是gs,s是把\n也當成小數點(任意字元),所以第一行的Definition for table可以比對下N行的End of definition。以下飯粒有標紅字是這兩大重點。

#!/usr/bin/perl
sub handleBlock {
    my $block = shift;
    @lines = split/\n/, $block;
    print $lines[0] . "\n";
}

undef $/;
open F, "./javaue.def" or die "$!";
$ctx = <F>;
close F;

while ($ctx =~ /(Definition for table .*?End of definition)/gs) {
    handleBlock($1);
}

(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(2) 人氣(542)

  • 個人分類:Regex
▲top
  • 10月 04 週一 201019:57
  • Java在換行字元的issue

摘自http://catchtest.pixnet.net/blog/post/21981758網站:

換行符號有兩種,一個叫Cr(carriage return),一個是Lf(line feed)
Ascii code分別是13(0d)跟10(0a)
Cr是將指標移到最前頭(回車)
Lf是跳到下一行的位置,但沒有跳到開頭的效果
合在一起就是把指標移到下一行的最前面
類似我們按Enter的效果

不巧的是,三大作業系統的換行符號定義都不一樣
Mac只有Cr
Linux/Unix只有Lf
Windows則是CrLf,兩者皆有
意思是Linux只需要Lf一個字元就可以有換行加移到前面的效果
但是Windows就需要兩個

   而我用Java的String的split("\n")去做分割字串,也真的只對Lf(0x0a)有效。因為同時因應\n、\r、\r\n以及不正常的\n\r,其Regex應是\n\r?|\r\n?   在用Java IO套件的BufferedReader去readLine,發現它讀到\r或\n都會截止,萬一\r或\n也是資料的一部份就會有問題。最後寫法變成使用FileInputStream將檔案讀進byte array,遇到\r換成\\r,遇到\n換成\\n,等處理完之後再置換回來。此外,Java String使用Unicode表示法如:\u0041、\uA440。可以使用\u0001..\u0009、\u000B、\u000F等。可是偏不能使用這對換字完,也就是使用\u000A和\u000D會無法通過編譯。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(2,912)

  • 個人分類:Regex
▲top
  • 9月 17 週五 201020:34
  • Perl在crontab的雞絲

  最初用Perl來Code Generate和Parse Log,現在可以變成專案交付的程式之一了。實作兩個不錯用的工具程式,可以設定於crontab。因為沒設定Perl主題,姑且併到Regex吧! 第一個是用於偵測特定process是否陣亡,若陣亡予以重啟,並透過SMTP發Mail告警,這雖然也可以用bash辦到,但搞不好還有Run在Windows的需求。

#!/usr/bin/perl
use Net::SMTP; # Perl的SMTP套件,至少AIX有

my @procs = `ps -ef | grep MyCompany.jar`;
my $flag = '0';
for (@procs) {
    $flag = $_ unless (/grep/); # 下ps –ef | grep '關鍵字'後,連grep也是process之一,是故需予以排除
}
unless ($flag eq '0') {
    print "Running [$flag]\n";  # 找到正在Run的MyCompany.jar,不做任何處理。
} else {
    my $msg = << 'END';  # 使用Here Document,SMTP採key: value配,From和To可以省略,Subject後需空一列才是Mail內容開始
From: Jemmy <jemmy@mycompany>
Subject: Warning

MyCompany.jar is offline!! launcher.pl will start it.
END

    my $smtp = Net::SMTP->new('10.1.2.3', Timeout=>60);
    my $success = $smtp->mail('admin@mycompany');            # mail(指定寄件人)
    $smtp->recipient('Jemmy <jemmy@mycompany>', {SkipBad=>1}); # 指定收件人,用逗號分隔或用@array
    $smtp->data($msg);
    $smtp->dataend;                                          # 信件結束,相當於使用小數點(參考下文)
    $smtp->quit;
    print "Start MyCompany.jar...\n";
    system "nohup ./run.sh &"; # run.sh內容像java –jar MyCompany.jar
}

  上述的程式,是仿照使用telnet呼叫smtp的命令列,在,內容如下:

oracle10@jemmy/ogg $ telnet 10.1.2.3 smtp –> 可以進入SMTP交互命令,粗體字是由User手動輸入
Trying...
Connected to 10.1.2.3
Escape character is '^]'.
220 mycompany.com.tw ESMTP Service (Lotus Domino Release 6.5.6FP2) ready at Fri, 17 Sep 2010
10:33:10 +0800
HELO 10.1.2.3 –> 和SMTP主機打招呼
250 tpoates02.fpg.com.tw Hello 10.1.2.3 ([10.1.2.99]), pleased to meet you
MAIL From: <admin@mycompany>
250 edpadmin@edp... Sender OK
RCPT To: <jemmy@mycompany>
250 edpadmin/edp@edp... Recipient OK
DATA –> 要求輸入信件內容了,按小數點結束,上述Perl的dataend即是這種作用。
354 Enter message, end with "." on a line by itself
From: Admin <admin@mycompany>
To: Jemmy <jemmy@mycompanyp>
Subject: Test by command


Hello! Nobody but you!
.
250 Message accepted for delivery
QUIT –> 離開SMTP交互模式
221 mycompany.com.tw SMTP Service closing transmission channel
Connection closed.

此外可以在Perl使用datasend替代data,如下飯粒,只不過要小心datasend和dataend是一字之差的method:

$smtp->data();
$smtp->datasend("To: $to\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("\n");
$smtp->datasend("Your Message");
$smtp->dataend();

第二個是定期備份Log,是用perl呼叫Unix的tar及compress命令,應該不能移植到Windows。

#!/usr/bin/perl

chdir "/ogg/logs";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon++;        # month base 0
$year+=1900;   # year base 1900
my $now = sprintf("%04d%02d%02d", $year, $mon, $mday);
# print "$now\n";
my @files = glob "com.systex.*.log *.gz";
my @tars = ();
for my $file (@files) {
    if ($file =~ /.+(\d{4})-(\d{2})-(\d{2})\.log(\.\d+\.gz)?/) {
        my $fdate = $1 . $2 . $3;
        if ($fdate ne $now) {
            push @tars, $file;
        }
    }
}
my $tar = "tar cvf LOG$now.tar " . join(' ', @tars);
system $tar;
system "compress LOG$now.tar ";
for my $file (@tars) {
    unlink $file or warn "$file remove error: $!\n";
}
print "finish!!\n";

Perl在日期時間的比較不甚方便,與其這樣,乾脆直接比出不等於今天的yyyy-mm-dd格式的檔案列為tar檔清單。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(130)

  • 個人分類:Regex
▲top
  • 9月 06 週一 201022:46
  • Java的跨行比對

  在家加班會有點不甘願,但研究和工作有關的技能倒還可以。Java在Regex的跨行比對有點彆扭,用來解析非XML、具Block性質的配置檔會比較清晰。需求如下:

*
*
Definition for table TESTUTF8.T1
Record length: 112
Syskey: 0
Columns: 2
C1   64     50        0  0  0 1 0     50     50     50 0 0 0 0 1    0 1 2
C2   64     50       56  0  0 1 0     50     50      0 0 0 0 0 1    0 0 0
End of definition

* TEST T2
Definition for table TESTUTF8.T2
Record length: 112
Syskey: 0
Columns: 2
C1   64     50        0  0  0 1 0     50     50     50 0 0 0 0 1    0 1 2
C2   64     50       56  0  0 1 0     50     50      0 0 0 0 0 1    0 0 0
End of definition

  如何在Java去group上述粗黑字的多行字串?逆向思考,跨行比對其實就是把它們當作一個單行,在Perl是用m(mulitline)參數,在Java使用Pattern物件要帶Patter.DOTALL參數,dot是一點,表示連換行字元都列入比對範圍,是故要group上述的需求的Sample code如下:

import java.io.FileInputStream;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRegexMultiLines {

    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("D:/javaue.def");
        byte[] ba = new byte[fis.available()];
        fis.read(ba);
        String javadef = new String(ba);
       
Pattern pat = Pattern.compile("Definition for table .*?End of definition",
            Pattern.DOTALL);

        Matcher mat = pat.matcher(javadef);
        while (mat.find()) {
            System.out.println("========================");
            System.out.println(mat.group());
        }
    }
}

  這樣就能找到兩筆group,因為有Pattern.DOTALL,小數點比對就包括了換行字元。另一個是*?這個不貪多量詞,找到符合pattern的最小字串,否則會變成找到一筆group,包括非粗體字都被包括進去。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(228)

  • 個人分類:Regex
▲top
  • 8月 11 週三 201022:53
  • XML特殊字元的比對

  在XML的特殊字元有五:<、>、&、'、"。通常轉特殊字元方式是像把&轉成&amp;。另一種不轉的方式,就是加<![CDATA[><&'" ]]>包覆。所以我有個需求是,避免產出的XML檔變肥,遇到有特殊字元的值,才用<![CDATA[… ]]>包覆。在Java借助Regex方式如下: colValue.matches(".*[><&'\"].*")   Java字串的matches方法一定要全域match,所以中括號裡的特殊字元前後都要加.*。   如果還有換行字元的情況怎麼辦?只能這樣比對: colValue.replaceAll("\n", "").matches(".*[><&'\"].*")
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(1,178)

  • 個人分類:Regex
▲top
  • 7月 14 週三 201018:53
  • Java Regex轉\uNNNN為Unicode字元

  在為轉碼傷腦筋時,曾想把內碼轉成Unicode表示法如:\u4E00的字串混過去。雖然後來不用,不過運用Java Regex把Unicode表示法轉成Unicode字元可以一記:

str = "ABC\\u7CBE\\u8AA0";
Pattern pat = Pattern.compile(“\\\\u([0-9A-F]{4})”); // Unicode表示法\uNNNN
Matcher mat = pat.matcher(str);
while (mat.find()) {
    str = mat.replaceFirst(String.format("%c", (char) Integer.parseInt(mat.group(1), 16)));
    // group(1)記憶括號裡的[0-9A-F]{4}以16進位轉成char型態。然後置換第一個(replaceFirst)
    mat = pat.matcher(str); // 置換後變成: ABC精\\u8AA00,再重設一次就會找到下一個\uNNNN
}

  跟Perl比起來,Java相對麻煩許多。主要是replaceFirst或replaceAll的第二個參數replacement無法程式化,最多只能format。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(281)

  • 個人分類:Regex
▲top
  • 5月 14 週五 201021:38
  • 千分位

  有個看我的Blog而加入我的msn一個網友,有個Regex問題如下: 1101,"24,236,136","7,256","641,351,276","123",25.50,27.10,25.50,26.60,+,1.20,26.55,213,26.60,125,10.73   按逗號split數字,但雙引號內的逗號是千分位,不能當作分隔號。若沒有千分位,Regex很好下:"?,"?。有千分位的話,Google的結果也不能一次解決,只能看位數長度再看Regex怎麼下,玩這個只是練功,效能未必好。程式片段如下:

String s = "1101,\"24,236,136\",\"7,256\",\"641,351,276\",\"123\",25.50,27.10,25.50,26.60,+,1.20,26.55,213,26.60,125,10.73";
System.out.println(s);
String s3 = s.replaceAll("\"(\\d{1,3})((,(\\d{3}))(,(\\d{3}))?)?\"", "$1$4$6");
System.out.println(s3);

得到結果是:

1101,"24,236,136","7,256","641,351,276","123",25.50,27.10,25.50,26.60,+,1.20,26.55,213,26.60,125,10.73
1101,24236136,7256,641351276,123,25.50,27.10,25.50,26.60,+,1.20,26.55,213,26.60,125,10.73

上述Regex Pattern只能到九位數,六位數的話應是:s.replaceAll("\"(\\d{1,3})(,(\\d{3}))?\"", "$1$3");。 若十二位數:s.replaceAll("\"(\\d{1,3})((,(\\d{3}))((,(\\d{3}))(,(\\d{3}))?)?)?\"", "$1$4$7$9");   目前並沒有相對於+、?、*及{m, n}的量詞group。不知更新版的Perl有無進化。在今年的OSDC看Perl簡報內容,其實已將Perl 5.x和Perl 6視為兩種不同的語言了。不過學到Regular Expression這麼好用的工具,要感謝過去的他,現在的她,未來的祂(因為還不肯定)。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(4) 人氣(485)

  • 個人分類:Regex
▲top
  • 4月 29 週四 201018:40
  • Date的Java Regex

  原本妄想繼承LazyValidatorForm來避免繼承ActionServlet,就不用動到web.xml設定達到Date型態通透性。結果是不可能,不過倒是玩了一下下日期在Regex的判斷:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestRegex {

    public static void main(String[] args) {
        Pattern pat = Pattern.compile("^(\\d{4})[\\/\\-](0?[1-9]|1[0-2])[\\/\\-]([012]\\d?|3[01]|[3-9]\\b)");
        String tests [] = {
               
"2010/4/29",
                "2010-4-29",

                "2010/13/29",
                "2010/4/32",
                "2010/04/06",
                "2010/24/06",
               
"2010/9/6",
                "2010/05/30 16:14:20",
                "2010/2/31",

        };

        Matcher mat;
        for (int i=0; i<tests.length; i++){
            mat = pat.matcher(tests[i]);
            System.out.print("input: "+tests[i]+" ");
            if (mat.find())
                System.out.println("matched with: "+mat.group() + " # " + mat.group(3));
            else
                System.out.println("didn't match.");
        }
    }
}

  紅字部份表示match,其中group(3)的日,限定到1~31,個位數可以前補0。美中不足的是,2/31這個日期也能pass,而Java的DateFormat也提供檢驗的method,使用方式如下:

public static boolean isValidDateStr(String date) {
    try {
        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); // YYYY/MM/DD 短日期格式
        df.setLenient(false);   // Lenient:寛鬆,設為false亦即2/31也不能pass
        df.parse(date);
    } catch (ParseException e) {
        return false;
    } catch (IllegalArgumentException e) {
        return false;
    }
    return true;
}

(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(378)

  • 個人分類:Regex
▲top
  • 6月 26 週五 200917:33
  • Oracle的REGEXP_LIKE

  好像是Oracle 10g以上才有SQL支援Regex的語法,SQL本身就是宿主語言,Regex又寄宿在SQL上,真是宿主的宿主。   假設Student Table的學號(STD_NO)有:1001~1100,有個Property有key_name和value_context兩個欄位,是key-value值,其中一筆:key_name值為Black,value_context值為1002,1009,1099。如何以一行SQL,把Student table濾掉Black所指定的以逗號分割的學號。 Select A.* from Student A, Property B where B.key_name='Black' and Not REGEXP_LIKE (A.STD_NO, replace(B.value_context, ',', '|'))   也就是先用replace函數把逗號(,)換成中線(|)符合Regexp_Like進行Regex比對,因是Not Regexp_Like,所以學號(STD_NO)符合在value_context裡都不會被Select出來。 P.S: 原來 Oracle 10g 開始就有提供 Regular Expression 了. 目前提供了 4 個 function, 分別是 REGEXP_LIKE, REGEXP_INSTR, REGEXP_SUBSTR 和 REGEXP_REPLACE, 相對於以前的 LIKE, INSTR, SUBSTR 以及 REPLACE
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(1,482)

  • 個人分類:Regex
▲top
12»

自訂側欄

自訂側欄

個人資訊

Jemmy
暱稱:
Jemmy
分類:
不設分類
好友:
累積中
地區:

熱門文章

  • (18,362)Windows route初體驗
  • (2,912)Java在換行字元的issue
  • (1,417)非我族類的DataTables.js:分頁和排序無作用原因
  • (1,319)Oracle的Array型態定義與存取
  • (776)OGG for Java開發
  • (577)Struts-Menu初體驗
  • (542)Perl的跨行比對
  • (436)ORA-08002
  • (73)Notes的Agent二三事
  • (33)六句聯

文章分類

  • PostgreSQL (1)
  • Ruby (6)
  • 圖書 (18)
  • 旅行 (8)
  • OSGi (13)
  • 健康 (9)
  • Google (6)
  • 歷史 (5)
  • Spring-Security (5)
  • Java Script (11)
  • Log (8)
  • 娛樂 (25)
  • IT趨勢 (12)
  • 心情 (92)
  • 組織 (41)
  • Java基本功 (18)
  • Regex (19)
  • 新聞與政治 (46)
  • 電腦和網際網路 (47)
  • Maven (28)
  • Spring (31)
  • LotusNotes (12)
  • Java (60)
  • Oracle (17)
  • Struts (21)
  • jQuery (10)
  • 未分類文章 (1)

最新文章

  • JDOM解析XML字串(非檔案)
  • Android SDK不能用於JDK 64bit
  • 非我族類的DataTables.js:分頁和排序無作用原因
  • java.lang.IllegalStateException: Committed之解
  • PostgreSQL二三事
  • Form/Field V.S. Document/Item
  • Spring Mail
  • Ant generate manifest.mf的class-path清單
  • dhcp.bat
  • Java update Notes的DateTime欄位

最新留言

  • [21/07/31] D 於文章「複習一下Servlet的機制...」留言:
    請問更換瀏覽器 Servlet的instance vari...
  • [17/05/04] 訪客 於文章「設定Source編碼...」留言:
    謝謝你~~...
  • [15/08/23] 洪秀柱 於文章「UltraEdit轉大小寫...」留言:
    此破解法可用於 UEstudio UltraEdit V2...
  • [10/10/15] Jemmy 於文章「Perl的跨行比對...」留言:
    哈! 學長, 好久不見了。幸虧這案子沒有Nested Tag...
  • [10/10/14] Benson 於文章「Perl的跨行比對...」留言:
    如果有Nested Tag, 這就不太適用; 我有時還是乖乖...
  • [10/05/25] 世文 於文章「JSON-Lib初體驗...」留言:
    用心經營的blog~^^ 加油!<br />---<br ...
  • [10/05/15] Jemmy 於文章「千分位...」留言:
    你的解法太高深了, 有空再練^^...
  • [10/05/14] Benson 於文章「千分位...」留言:
    可能是 gxe, 不管是 perl or java, 你懂我...
  • [10/05/14] Jemmy 於文章「千分位...」留言:
    練功一下而已, 而且我是要用Java,所以無法用Perl...
  • [10/05/14] Benson 於文章「千分位...」留言:
    學弟,你的問題是什麼呢?是把在引號內數字逗號去掉嗎?s/\"...

動態訂閱

文章精選

文章搜尋

誰來我家

參觀人氣

  • 本日人氣:
  • 累積人氣: