隨筆-314  評論-209  文章-0  trackbacks-0
           
          JDK工具 java命令詳解
          一、查看用法
           
          C:\>java -help
          Usage: java [-options] class [args...]
                     (to execute a class)
             or  java [-options] -jar jarfile [args...]
                     (to execute a jar file)
           
          where options include:
              -client       to select the "client" VM
              -server       to select the "server" VM
              -hotspot      is a synonym for the "client" VM  [deprecated]
                            The default VM is client.
           
              -cp <class search path of directories and zip/jar files>
              -classpath <class search path of directories and zip/jar files>
                            A ; separated list of directories, JAR archives,
                            and ZIP archives to search for class files.
              -D<name>=<value>
                            set a system property
              -verbose[:class|gc|jni]
                            enable verbose output
              -version      print product version and exit
              -version:<value>
                            require the specified version to run
              -showversion  print product version and continue
              -jre-restrict-search | -jre-no-restrict-search
                            include/exclude user private JREs in the version search
              -? -help      print this help message
              -X            print help on non-standard options
              -ea[:<packagename>...|:<classname>]
              -enableassertions[:<packagename>...|:<classname>]
                            enable assertions
              -da[:<packagename>...|:<classname>]
              -disableassertions[:<packagename>...|:<classname>]
                            disable assertions
              -esa | -enablesystemassertions
                            enable system assertions
              -dsa | -disablesystemassertions
                            disable system assertions
              -agentlib:<libname>[=<options>]
                            load native agent library <libname>, e.g. -agentlib:hprof
                              see also, -agentlib:jdwp=help and -agentlib:hprof=help
              -agentpath:<pathname>[=<options>]
                            load native agent library by full pathname
              -javaagent:<jarpath>[=<options>]
                            load Java programming language agent, see java.lang.instrument
           
          這個命令幫助是英文的,不知道JDK咋搞的,也不妨礙使用。
           
          另外,這個命令的非標準選項也是很重要的,常常在JVM優化配置方面很關鍵,可以參看本人的JVM參數配置文章。
          C:\myproject>java -X
              -Xmixed           mixed mode execution (default)
              -Xint             interpreted mode execution only
              -Xbootclasspath:<directories and zip/jar files separated by ;>
                                set search path for bootstrap classes and resources
              -Xbootclasspath/a:<directories and zip/jar files separated by ;>
                                append to end of bootstrap class path
              -Xbootclasspath/p:<directories and zip/jar files separated by ;>
                                prepend in front of bootstrap class path
              -Xnoclassgc       disable class garbage collection
              -Xincgc           enable incremental garbage collection
              -Xloggc:<file>    log GC status to a file with time stamps
              -Xbatch           disable background compilation
              -Xms<size>        set initial Java heap size
              -Xmx<size>        set maximum Java heap size
              -Xss<size>        set java thread stack size
              -Xprof            output cpu profiling data
              -Xfuture          enable strictest checks, anticipating future default
              -Xrs              reduce use of OS signals by Java/VM (see documentation)
              -Xcheck:jni       perform additional checks for JNI functions
              -Xshare:off       do not attempt to use shared class data
              -Xshare:auto      use shared class data if possible (default)
              -Xshare:on        require using shared class data, otherwise fail.
           
           
          二、實踐
           
          老規矩,主要看看里面的參數(也叫開關)的使用。環境接著上篇javac的環境。
           
           
          1、無參數情況
           
          2、-cp
          運行Java要使用類的全名來運行。如果遇到文件夾,則需要-cp設置到頂級包下面,例如
           
          3、-D
          設置一個系統屬性,在運行時候,可以通過System.getProperties()來獲取到。例如寫一段代碼:
          package com.lavasoft;

          import java.util.Properties;

          /**
          * 列舉系統的屬性
          * User: leizhimin
          * Date: 2008-11-12 21:25:08
          */

          public class TestProperty {
                  public static void main(String[] args) {
                          //獲取系統屬性
                          Properties prop = System.getProperties();
                          //輸出所有到一個流上,
                          prop.list(System.out);
                  }
          }
           
           
          如果在運行的時候加上一個參數-DmyProp=999999999,注意,中間不要添加任何空格。這樣就相當于設置了一個系統屬性myProp,其值為999999999。
           
          一旦通過-DmyProp=999999999設置了這個系統屬性,在程序中就可以獲取到這個屬性。
           
          3、程序入參
          是在運行的時候,給main方法傳遞參數。為了測試先寫一個測試類。
          package com.lavasoft;

          /**
          * 測試main方法的入參
          * User: leizhimin
          * Date: 2008-11-12 21:46:21
          */

          public class TestMainVar {
                  public static void main(String[] args) {
                          System.out.println("入參列表如下:");
                          for(String arg:args){
                                  System.out.println(arg);
                          }
                  }
          }
           
           
          4、其他的選項
          有關選擇 客戶端/服務端VM、版本、運行在哪個版本下、是否使用斷言等一些不常用的選項。還可以查看
           
           
          5、-verbose[:class|gc|jni]
          查看虛擬機內部動作。
           
           
           
          posted @ 2009-12-04 17:15 xzc 閱讀(18018) | 評論 (4)編輯 收藏

          結構

          javac [ options ] [ sourcefiles ] [ @files ]
          

          參數可按任意次序排列。

          options
          命令行選項。
          sourcefiles
          一個或多個要編譯的源文件(例如 MyClass.java)。
          @files
          一個或多個對源文件進行列表的文件。

          說明

          javac

          有兩種方法可將源代碼文件名傳遞給 javac:

          • 如果源文件數量少,在命令行上列出文件名即可。
          • 如果源文件數量多,則將源文件名列在一個文件中,名稱間用空格或回車行來進行分隔。然后在 javac 命令行中使用該列表文件名,文件名前冠以 @ 字符。

          源代碼文件名稱必須含有 .java 后綴,類文件名稱必須含有 .class 后綴,源文件和類文件都必須有識別該類的根名。例如,名為 MyClass 的類將寫在名為 MyClass.java的源文件中,并被編譯為字節碼類文件 MyClass.class

          內部類定義產生附加的類文件。這些類文件的名稱將內部類和外部類的名稱結合在一起,例如 MyClass$MyInnerClass.class

          應當將源文件安排在反映其包樹結構的目錄樹中。例如,如果將所有的源文件放在 /workspace 中,那么 com.mysoft.mypack.MyClass 的代碼應該在 \workspace\com\mysoft\mypack\MyClass.java 中。

          缺省情況下,編譯器將每個類文件與其源文件放在同一目錄中。可用 -d 選項(請參閱后面的選項)指定其它目標目錄。

          工具讀取用 Java 編程語言編寫的類和接口定義,并將它們編譯成字節碼類文件。

          查找類型

          當編譯源文件時,編譯器常常需要它還沒有識別出的類型的有關信息。對于源文件中使用、擴展或實現的每個類或接口,編譯器都需要其類型信息。這包括在源文件中沒有明確提及、但通過繼承提供信息的類和接口。

          例如,當擴展 java.applet.Applet 時還要用到 Applet 的祖先類:java.awt.Paneljava.awt.Containerjava.awt.Componentjava.awt.Object

          當編譯器需要類型信息時,它將查找定義類型的源文件或類文件。編譯器先在自舉類及擴展類中查找,然后在用戶類路徑中查找。用戶類路徑通過兩種途徑來定義:通過設置 CLASSPATH 環境變量或使用 -classpath 命令行選項。(有關詳細資料,請參閱設置類路徑)。如果使用 -sourcepath 選項,則編譯器在 sourcepath 指定的路徑中查找源文件;否則,編譯器將在用戶類路徑中查找類文件和源文件。可用-bootclasspath-extdirs 選項來指定不同的自舉類或擴展類;參閱下面的聯編選項。

          成功的類型搜索可能生成類文件、源文件或兩者兼有。以下是 javac 對各種情形所進行的處理:

          • 搜索結果只生成類文件而沒有源文件: javac 使用類文件。
          • 搜索結果只生成源文件而沒有類文件: javac 編譯源文件并使用由此生成的類文件。
          • 搜索結果既生成源文件又生成類文件: 確定類文件是否過時。若類文件已過時,則 javac 重新編譯源文件并使用更新后的類文件。否則, javac 直接使用類文件。

            缺省情況下,只要類文件比源文件舊, javac 就認為它已過時。( -Xdepend 選項指定相對來說較慢但卻比較可靠的過程。)

            javac

          注意: javac 可以隱式編譯一些沒有在命令行中提及的源文件。用 -verbose 選項可跟蹤自動編譯。

          文件列表

          為縮短或簡化 javac 命令,可以指定一個或多個每行含有一個文件名的文件。在命令行中,采用 '@' 字符加上文件名的方法將它指定為文件列表。當 javac 遇到以 `@' 字符開頭的參數時,它對那個文件中所含文件名的操作跟對命令行中文件名的操作是一樣的。這使得 Windows 命令行長度不再受限制。

          例如,可以在名為 sourcefiles 的文件中列出所有源文件的名稱。該文件可能形如:

               MyClass1.java
          MyClass2.java
          MyClass3.java
          

          然后可用下列命令運行編譯器:

               C:> javac @sourcefiles
          

          選項

          編譯器有一批標準選項,目前的開發環境支持這些標準選項,將來的版本也將支持它。還有一批附加的非標準選項是目前的虛擬機實現所特有的,將來可能要有變化。非標準選項以 -X 打頭。

          標準選項

          -classpath 類路徑
          設置用戶類路徑,它將覆蓋 CLASSPATH 環境變量中的用戶類路徑。若既未指定 CLASSPATH 又未指定 -classpath,則用戶類路徑由當前目錄構成。有關詳細信息,請參閱設置類路徑。

          若未指定 -sourcepath 選項,則將在用戶類路徑中查找類文件和源文件。

          -d 目錄
          設置類文件的目標目錄。如果某個類是一個包的組成部分,則 javac 將把該類文件放入反映包名的子目錄中,必要時創建目錄。例如,如果指定 -d c:\myclasses 并且該類名叫 com.mypackage.MyClass,那么類文件就叫作 c:\myclasses\com\mypackage\MyClass.class

          若未指定 -d 選項,則 javac 將把類文件放到與源文件相同的目錄中。

          注意: -d 選項指定的目錄不會被自動添加到用戶類路徑中。

          -deprecation
          顯示每種不鼓勵使用的成員或類的使用或覆蓋的說明。沒有給出 -deprecation 選項的話, javac 將顯示這類源文件的名稱:這些源文件使用或覆蓋不鼓勵使用的成員或類。
          -encoding
          設置源文件編碼名稱,例如 EUCJIS/SJIS。若未指定 -encoding 選項,則使用平臺缺省的轉換器。
          -g
          生成所有的調試信息,包括局部變量。缺省情況下,只生成行號和源文件信息。
          -g:none
          不生成任何調試信息。
          -g:{關鍵字列表}
          只生成某些類型的調試信息,這些類型由逗號分隔的關鍵字列表所指定。有效的關鍵字有:
          source
          源文件調試信息
          lines
          行號調試信息
          vars
          局部變量調試信息
          -nowarn
          禁用警告信息。
          -O
          優化代碼以縮短執行時間。使用 -O 選項可能使編譯速度下降、生成更大的類文件并使程序難以調試。

          在 JDK 1.2 以前的版本中,javac 的 -g 選項和 -O 選項不能一起使用。在 JDK 1.2 中,可以將 -g-O 選項結合起來,但可能會得到意想不到的結果,如丟失變量或重新定位代碼或丟失代碼。-O 選項不再自動打開 -depend 或關閉 -g 選項。同樣, -O 選項也不再允許進行跨類內嵌。

          -sourcepath 源路徑
          指定用以查找類或接口定義的源代碼路徑。與用戶類路徑一樣,源路徑項用分號 (;) 進行分隔,它們可以是目錄、JAR 歸檔文件或 ZIP 歸檔文件。如果使用包,那么目錄或歸檔文件中的本地路徑名必須反映包名。

          注意:通過類路徑查找的類,如果找到了其源文件,則可能會自動被重新編譯。

          -verbose
          冗長輸出。它包括了每個所加載的類和每個所編譯的源文件的有關信息。

          聯編選項

          缺省情況下,類是根據與 javac 一起發行的 JDK 自舉類和擴展類來編譯。但 javac 也支持聯編,在聯編中,類是根據其它 Java平臺實現的自舉類和擴展類來進行編譯的。聯編時, -bootclasspath-extdirs 的使用很重要;請參閱下面的聯編程序示例。

          -target 版本
          生成將在指定版本的虛擬機上運行的類文件。缺省情況下生成與 1.1 和 1.2 版本的虛擬機都兼容的類文件。JDK 1.2 中的 javac 所支持的版本有:
          1.1
          保證所產生的類文件與 1.1 和 1.2 版的虛擬機兼容。這是缺省狀態。
          1.2
          生成的類文件可在 1.2 版的虛擬機上運行,但不能在 1.1 版的虛擬機上運行。
          -bootclasspath 自舉類路徑
          根據指定的自舉類集進行聯編。和用戶類路徑一樣,自舉類路徑項用分號 (;) 進行分隔,它們可以是目錄、JAR 歸檔文件或 ZIP 歸檔文件。
          -extdirs 目錄
          根據指定的擴展目錄進行聯編。目錄是以分號分隔的目錄列表。在指定目錄的每個 JAR 歸檔文件中查找類文件。

          非標準選項

          -X
          顯示非標準選項的有關信息并退出。
          -Xdepend
          遞歸地搜索所有可獲得的類,以尋找要重編譯的最新源文件。該選項將更可靠地查找需要編譯的類,但會使編譯進程的速度大為減慢。
          -Xstdout
          將編譯器信息送到System.out 中。缺省情況下,編譯器信息送到 System.err 中。
          -Xverbosepath
          說明如何搜索路徑和標準擴展以查找源文件和類文件。
          -J選項
          選項傳給 javac 調用的 java 啟動器。例如, -J-Xms48m 將啟動內存設為 48 兆字節。雖然它不以 -X 開頭,但它并不是 javac 的‘標準選項’。用 -J 將選項傳給執行用 Java 編寫的應用程序的虛擬機是一種公共約定。

          注意: CLASSPATH-classpath-bootclasspath-extdirs 指定用于運行 javac 的類。如此濫用編譯器的實現通常沒有任何意義而且總是很危險的。如果確實需要這樣做,可用 -J 選項將選項傳給基本的 java 啟動器。

          程序示例

          編譯簡單程序

          一個源文件 Hello.java ,它定義了一個名叫 greetings.Hello 的類。greetings 目錄是源文件和類文件兩者的包目錄,且它不是當前目錄。這讓我們可以使用缺省的用戶類路徑。它也使我們沒必要用 -d 選項指定單獨的目標目錄。

          C:> dir
          greetings/
          C:> dir greetings
          Hello.java
          C:> cat greetings\Hello.java
          package greetings;
          public class Hello {
          public static void main(String[] args) {
          for (int i=0; i < args.length; i++) {
          System.out.println("Hello " + args[i]);
          }
          }
          }
          C:> javac greetings\Hello.java
          C:> dir greetings
          Hello.class   Hello.java
          C:> java greetings.Hello World Universe Everyone
          Hello World
          Hello Universe
          Hello Everyone
          

          編譯多個源文件

          該示例編譯 greetings 包中的所有源文件。

          C:> dir
          greetings\
          C:> dir greetings
          Aloha.java         GutenTag.java      Hello.java         Hi.java
          C:> javac greetings\*.java
          C:> dir greetings
          Aloha.class         GutenTag.class      Hello.class         Hi.class
          Aloha.java          GutenTag.java       Hello.java          Hi.java
          

          指定用戶類路徑

          對前面示例中的某個源文件進行更改后,重新編譯它:

          C:> cd
          \examples
          C:> javac greetings\Hi.java
          

          由于 greetings.Hi 引用了 greetings 包中其它的類,編譯器需要找到這些其它的類。上面的示例能運行是因為缺省的用戶類路徑剛好是含有包目錄的目錄。但是,假設我們想重新編譯該文件并且不關心我們在哪個目錄中的話, 我們需要將 \examples 添加到用戶類路徑中。可以通過設置 CLASSPATH 達到此目的,但這里我們將使用 -classpath 選項來完成。

          C:>javac -classpath \examples \examples\greetings\Hi.java
          

          如果再次將 greetings.Hi 改為使用標題實用程序,該實用程序也需要通過用戶類路徑來進行訪問:

          C:>javac -classpath \examples:\lib\Banners.jar \
          \examples\greetings\Hi.java
          

          要執行 greetings 中的類,需要訪問 greetings 和它所使用的類。

          C:>java -classpath \examples:\lib\Banners.jar greetings.Hi
          

          將源文件和類文件分開

          將源文件和類文件置于不同的目錄下經常是很有意義的,特別是在大型的項目中。我們用 -d 選項來指明單獨的類文件目標位置。由于源文件不在用戶類路徑中,所以用 -sourcepath 選項來協助編譯器查找它們。

          C:> dir
          classes\  lib\      src\
          C:> dir src
          farewells\
          C:> dir src\farewells
          Base.java      GoodBye.java
          C:> dir lib
          Banners.jar
          C:> dir classes
          C:> javac -sourcepath src -classpath classes:lib\Banners.jar \
          src\farewells\GoodBye.java -d classes
          C:> dir classes
          farewells\
          C:> dir classes\farewells
          Base.class      GoodBye.class
          

          注意:編譯器也編譯了 src\farewells\Base.java,雖然我們沒有在命令行中指定它。要跟蹤自動編譯,可使用 -verbose 選項。

          聯編程序示例

          這里我們用 JDK 1.2 的 javac 來編譯將在 1.1 版的虛擬機上運行的代碼。

          C:> javac -target 1.1 -bootclasspath jdk1.1.7\lib\classes.zip \
          -extdirs "" OldCode.java
          

          -target 1.1

          JDK 1.2 javac 在缺省狀態下也將根據 1.2 版的自舉類來進行編譯,因此我們需要告訴 javac 讓它根據 JDK 1.1 自舉類來進行編譯。可用 -bootclasspath-extdirs 選項來達到此目的。不這樣做的話,可能會使編譯器根據 1.2 版的 API 來進行編譯。由于 1.1 版的虛擬機上可能沒有該 1.2 版的 API,因此運行時將出錯。

          選項可確保生成的類文件與 1.1 版的虛擬機兼容。在 JDK1.2 中, 缺省情況下 javac 編譯生成的文件是與 1.1 版的虛擬機兼容的,因此并非嚴格地需要該選項。然而,由于別的編譯器可能采用其它的缺省設置,所以提供這一選項將不失為是個好習慣。
          posted @ 2009-12-04 17:13 xzc 閱讀(408) | 評論 (0)編輯 收藏

          Java命令行命令詳解

          rmic

          功能說明:
            rmic 為遠程對象生成 stub 和 skeleton。

          語法:
            rmic [ options ] package-qualified-class-name(s)

          補充說明:
            rmic 編譯器根據編譯后的 Java 類(含有遠程對象實現)名,為遠程對象生成 stub 和 skeleton(遠程對象是指實現 java.rmi.Remote 接口的對象)。在 rmic 命令中所給的類必須是經 javac 命令成功編譯且是完全包限定的類。

          命令選項
            -classpath[路徑] 指定 rmic 用于查詢類的路徑。如果設置了該選項,它將覆蓋缺省值或 CLASSPATH 環境變量。目錄用冒號分隔。


            -d[目錄] 指定類層次的根目錄。此選項可用來指定 stub 和 skeleton 文件的目標目錄。


            -depend 使編譯器考慮重新編譯從其它類引用的類。 一般來說,它只重新編譯從源代碼引用的遺漏或過期的類。

            -g 允許生成調試表格。調試表格含有行號和局部變量的有關信息,即 Java 調試工具所使用的信息。缺省情況下,只生成行號。

            -J 與 -D 選項聯用,它將緊跟其后的選項( -J 與 -D 之間無空格)傳給 java 解釋器。

            -keepgenerated 為 stub 和 skeleton 文件保留所生成的 .java 源文件,并將這些源文件寫到與 .class 文件相同的目錄中,如果要指定目錄,則使用 -d 選項。

            -nowarn 關閉警告。如果使用該選項,則編譯器不輸出任何警告信息。

            -show 顯示 rmic 編譯器的 GUI(圖形用戶界面)。輸入一個或多個包限定類名(以空格分隔),并按回車鍵或“顯示”按鈕,創建 stub 和 skeleton。

            -vcompat (缺省值)創建與 JDK 1.1 和 1.2 stub 協議版本都兼容的 stub 和 skeleton。

            -verbose 使編譯器和鏈接器輸出關于正在編譯哪些類和正在加載哪些類文件的信息。

            -v1.1 創建 JDK 1.1 stub 協議版本的 stub 和 skeleton。

            -v1.2 只創建 JDK 1.2 stub 協議版本的 stub。


          rmid

          功能說明:
            rmid 啟動激活系統守護進程,以便能夠在 Java 虛擬機上注冊和激活對象。

          語法:
            rmid [-port port] [-log dir]

          補充說明:
            rmid 工具啟動激活系統守護進程。必須先啟動激活系統守護進程,才能向激活系統注冊可被激活的對象或在 Java 虛擬機上激活可被激活的對象。

          命令選項
            -C<某些命令行選項> 指定一個選項,在創建每個 rmid 的子守護進程(激活組)時,該選項以命令行參數的形式傳給該子守護進程。

            -log[目錄] 指定目錄的名稱,激活系統守護進程在該目錄中寫入其數據庫及相關信息。缺省狀態下,將在執行 rmid 命令的目錄中創建一個 log 目錄。

            -port[端口] 指定 rmid 的注冊服務程序所使用的端口。激活系統守護進程將 ActivationSystem 與該注冊服務程序中的名稱java.rmi.activation.ActivationSystem 捆綁在一起。

            -stop 停止 -port 選項所指定端口上的當前 rmid 調用。若未指定端口,則將停止在端口 1098 上運行的 rmid。

          rmiregistry

          功能說明:
            rmiregistry 命令可在當前主機的指定端口上啟動遠程對象注冊服務程序。

          語法:
            rmiregistry [port]

          補充說明:
             rmiregistry 命令在當前主機的指定 port 上創建并啟動遠程對象注冊服務程序。如果省略 port,則注冊服務程序將在 1099 端口上啟動。rmiregistry 命令不產生任何輸出而且一般在后臺運行。遠程對象注冊服務程序是自舉命名服務。主機上的 RMI 服務器將利用它將遠程對象綁定到名字上。客戶機即可查詢遠程對象并進行遠程方法調用。注冊服務程序一般用于定位應用程序需調用其方法的第一個遠程對象。該 對象反過來對各應用程序提供相應的支持,用于查找其它對象。

            java.rmi.registry.LocateRegistry 類的方法可用于在某臺主機或主機和端口上獲取注冊服務程序操作。java.rmi.Naming 類的基于 URL 的方法將對注冊服務程序進行操作,并可用于查詢遠程對象、將簡單(字符串)名稱綁定到遠程對象、將新名稱重新綁定到遠程對象(覆蓋舊綁定)、取消遠程對象 的綁定以及列出綁定在注冊服務程序上的 URL。

          serialver

          功能說明:
            serialver 命令返回 serialVersionUID。

          語法:
            serialver [ 命令選項 ]

          補充說明:
            serialver 以適于復制到演變類的形式返回一個或多個類的 serialVersionUID。不帶參數調用時,它輸出用法行。

          命令選項
            -show 顯示一個簡單的用戶界面。輸入完整的類名并按回車鍵或“顯示”按鈕可顯示 serialVersionUID。

          jarsigner

          功能說明:
            為 Java 歸檔 (JAR) 文件產生簽名,并校驗已簽名的 JAR 文件的簽名。

          語法:
            jarsigner [ 命令選項 ] jar-file alias
            jarsigner -verify [ 命令選項 ] jar-file

          補充說明:
            jarsigner 工具用于兩個目的:
            1:為 Java 歸檔 (JAR) 文件簽名
            2:校驗已簽名的 JAR 文件的簽名和完整性

          命令選項
            -keystore[url] 指定密鑰倉庫的 URL。缺省值是用戶的宿主目錄中的 .keystore 文件,它由系統屬性“user.home”決定。

            -storetype[storetype] 指定要被實例化的密鑰倉庫類型。默認的密鑰倉庫類型是安全屬性文件中 "keystore.type" 屬性值所指定的那個類型,由 java.security.KeyStore 中的靜態方法 getDefaultType 返回。

            -storepass[password] 指定訪問密鑰倉庫所需的口令。這僅在簽名(不是校驗)JAR 文件時需要。在這種情況下,如果命令行中沒有提供 -storepass 選項,用戶將被提示輸入口令。

            -keypass[password] 指定用于保護密鑰倉庫項(由命令行中指定的別名標出)的私鑰的口令。使用 jarsigner 為 JAR 文件簽名時需要該口令。如果命令行中沒有提供口令,且所需的口令與密鑰倉庫的口令不同,則將提示用戶輸入它。

            -sigfile[file] 指定用于生成 .SF 和 .DSA 文件的基本文件名。

            -signedjar[file] 指定用于已簽名的 JAR 文件的名稱。

             -verify 如果它出現在命令行中,則指定的 JAR 文件將被校驗,而不是簽名。如果校驗成功,將顯示“jar verified”。如果試圖校驗未簽名的 JAR 文件,或校驗被不支持的算法(例如未安裝 RSA 提供者時使用的 RSA)簽名的 JAR 文件,則將有如下顯示: "jar is unsigned. (signatures missing or not parsable)" 。

            -certs 如果它與 -verify 和 -verbose 選項一起出現在命令行中,則輸出將包括 JAR 文件的每個簽名人的證書信息。

            -verbose 如果它出現在命令行中,則代表“verbose”模式,它使 jarsigner 在 JAR 簽名或校驗過程中輸出額外信息。

             -internalsf 過去,JAR 文件被簽名時產生的 .DSA(簽名塊)文件包含一個同時產生的 .SF 文件(簽名文件)的完整編碼副本。這種做法已被更改。為了減小輸出 JAR 文件的整個大小,缺省情況下 .DSA 文件不再包含 .SF 文件的副本。但是如果 -internalsf 出現在命令行中,將采用舊的做法。該選項主要在測試時有用;實際上不應使用它,因為這樣將消除有用的優化。

            -sectionsonly 如果它出現在命令行中,則 JAR 文件被簽名時生成的 .SF 文件(簽名文件)將不包括含有整個清單文件的散列的頭。它僅包含 與 JAR 中每個單獨的源文件相關的信息和散列。該選項主要在測試時有用;實際上不應使用它,因為這樣將消除有用的優化。

            -J [javaoption] 將指定的 javaoption 串直接傳遞到 Java 解釋器。((jarsigner 實際上是解釋器的一個 “wrapper”)。該選項不應含有任何空格。它有助于調整執行環境或內存使用。要獲得可用的解釋器選項的清單,可在命令行鍵入 java -h 或 java -X。

          keytool

          功能說明:
            管理由私鑰和認證相關公鑰的 X.509 證書鏈組成的密鑰倉庫(數據庫)。還管理來自可信任實體的證書。

          語法:
            keytool [ 命令 ]

          補充說明:
            keytool 是個密鑰和證書管理工具。它使用戶能夠管理自己的公鑰/私鑰對及相關證書,用于(通過數字簽名)自我認證(用戶向別的用戶/服務認證自己)或數據完整性以及認證服務。它還允許用戶儲存他們的通信對等者的公鑰(以證書形式)。

          native2ascii

          功能說明:
            將含有本地編碼字符(既非 Latin1 又非 Unicode 字符)的文件轉換為 Unicode 編碼字符的文件。

          語法:
            native2ascii [options] [inputfile [outputfile]]

          補充說明:
            Java 編譯器和其它 Java 工具只能處理含有 Latin-1 和/或 Unicode 編碼(udddd 記號)字符的文件。native2ascii 將含有其它字符編碼的文件轉換成含 Latin-1 和/或 Unicode 編碼字符的文件。若省略 outputfile,則使用標準輸出設備輸出。此外,如果也省略 inputfile,則使用標準輸入設備輸入。

          命令選項
            -reverse 執行相反的操作:將含 Latin-1 和/或 Unicode 編碼字符的文件轉換成含本地編碼字符的文件。

            -encoding[encoding_name] 指定轉換過程使用的編碼名稱。缺省的編碼從系統屬性 file.encoding 中得到。

          appletviewer

          功能說明:
            Java applet 瀏覽器。appletviewer 命令可在脫離萬維網瀏覽器環境的情況下運行 applet。

          語法:
            appletviewer [ threads flag ] [ 命令選項 ] urls ...

          補充說明:
             appletviewer 命令連接到 url 所指向的文檔或資源上,并在其自身的窗口中顯示文檔引用的每個 applet。注意:如果 url 所指向的文檔不引用任何帶有 OBJECT、EMBED 或 APPLET 標記的 applet,那么 appletviewer 就不做任何事情。

          命令選項
            -debug 在 Java 調試器 jdb 中啟動 appletviewer,使您可以調試文檔中的 applet。

            -encoding[編碼名稱] 指定輸入 HTML 文件的編碼名稱。

             -J[javaoption] 將 javaoption 字符串作為單個參數傳給運行 appletviewer 的 Java 解釋器。參數不能含有空格。由多重參數組成的字符串,其中的每個參數都必須以前綴 -J 開頭,該前綴以后將被除去。這在調整編譯器的執行環境或內存使用時將很有用。

          extcheck

          功能說明:
            extcheck 檢測目標 jar 文件與當前安裝方式擴展 jar 文件間的版本沖突。

          語法:
            extcheck [ -verbose ] targetfile.jar

          補充說明:
            extcheck 實用程序檢查指定 Jar 文件的標題和版本與 JDK TM 軟件中所安裝的擴展是否有沖突。在安裝某個擴展前,可以用該實用程序查看是否已安裝了該擴展的相同版本或更高的版本。

             extcheck 實用程序將 targetfile.jar 文件清單的 specification-title 和 specification-version 頭與當前安裝在擴展目錄下所有 Jar 文件的相對應的頭進行比較(缺省擴展目錄為 jre/lib/ext)。extcheck 實用程序比較版本號的方式與 java.lang.Package.isCompatibleWith 方法相同。若未檢測到沖突,則返回代碼為 0。如果擴展目錄中任何一個 jar 文件的清單有相同的 specification-title 和相同的或更新的 specification-version 號,則返回非零錯誤代碼。如果 targetfile.jar 的清單中沒有 specification-title 或 specification-version 屬性,則同樣返回非零錯誤代碼。

          命令選項
            -verbose 對擴展目錄中的 Jar 文件進行檢查時,列出文件。此外,還報告目標 jar 文件的清單屬性及所有沖突的 jar 文件。

          jar

          功能說明:
            Java歸檔工具

          語法:
            jar [ 命令選項 ] [manifest] destination input-file [input-files]

          補充說明:
             jar工具是個java應用程序,可將多個文件合并為單個JAR歸檔文件。jar是個多用途的存檔及壓縮工具,它基于ZIP和ZLIB壓縮格式。然而, 設計jar的主要目的是便于將java applet或應用程序打包成單個歸檔文件。將applet或應用程序的組件(.class 文件、圖像和聲音)合并成單個歸檔文件時,可以用java代理(如瀏覽器)在一次HTTP事務處理過程中對它們進行下載,而不是對每個組件都要求一個新連 接。這大大縮短了下載時間。jar還能壓縮文件,從而進一步提高了下載速度。此外,它允許applet的作者對文件中的各個項進行簽名,因而可認證其來 源。jar工具的語法基本上與tar命令的語法相同。

          命令選項
            -c 在標準輸出上創建新歸檔或空歸檔。

            -t 在標準輸出上列出內容表。

            -x[file] 從標準輸入提取所有文件,或只提取指定的文件。如果省略了file,則提取所有文件;否則只提取指定文件。

            -f 第二個參數指定要處理的jar文件。在-c(創建)情形中,第二個參數指的是要創建的jar文件的名稱(不是在標準輸出上)。在-t(表(或-x(抽取)這兩種情形中,第二個參數指定要列出或抽取的jar文件。

            -v 在標準錯誤輸出設備上生成長格式的輸出結果。

            -m 包括指定的現有清單文件中的清單信息。用法舉例:“jar cmf myManifestFile myJarFile *.class”

            -0 只儲存,不進行 ZIP 壓縮。

            -M 不創建項目的清單文件。

             -u 通過添加文件或更改清單來更新現有的 JAR 文件。例如:“jar -uf foo.jar foo.class”將文件 foo.class 添加到現有的JAR文件foo.jar中,而“jar umf manifest foo.jar”則用manifest中的信息更新foo.jar的清單。

            -C 在執行 jar 命令期間更改目錄。例如:“jar -uf foo.jar -C classes *”將classes目錄內的所有文件加到foo.jar中,但不添加類目錄本身。

          程序示例
            1:將當前目錄下所有CLASS文件打包成新的JAR文件:
            jar cf file.jar *.class

            2:顯示一個JAR文件中的文件列表
            jar tf file.jar

            3:將當前目錄下的所有文件增加到一個已經存在的JAR文件中
            jar cvf file.jar *

          javadoc

          功能說明
            Java API文檔生成器從Java源文件生成API文檔HTML頁。

          語法:
            javadoc [ 命令選項 ] [ 包名 ] [ 源文件名 ] [ @files ]
            其中[ 包名 ]為用空格分隔的一系列包的名字,包名不允許使用通配符,如(*)。[ 源文件名 ]為用空格分隔的一系列的源文件名,源文件名可包括路徑和通配符,如(*)。[ @files ]是以任何次序包含包名和源文件的一個或多個文件。

          補充說明
            Javadoc解析Java源文件中的聲明和文檔注釋,并產生相應的HTML頁缺省),描述公有類、保護類、內部類、接口、構造函數、方法和域。

             在實現時,Javadoc要求且依賴于java編譯器完成其工作。Javadoc調用部分javac編譯聲明部分,忽略成員實現。它建立類的內容豐富的 內部表示,包括類層次和“使用”關系,然后從中生成HTML。Javadoc還從源代碼的文檔注釋中獲得用戶提供的文檔。

            當Javadoc建立其內部文檔結構時,它將加載所有引用的類。由于這一點,Javadoc必須能查找到所有引用的類,包括引導類、擴展類和用戶類。

          命令選項
            -overview i>path/filename 指定javadoc應該從path/filename所指定的“源”文件中獲取概述文檔,并將它放到概述頁中(overview- summary.html)。其中path/filename 是相對于-sourcepath的相對路徑名。

            -public 只顯示公有類及成員。

            -protected 只顯示受保護的和公有的類及成員。這是缺省狀態。

            -package 只顯示包、受保護的和公有的類及成員。

            -private 顯示所有類和成員。

            -help 顯示聯機幫助,它將列出這些javadoc和doclet命令行選項。

             -doclet class 指定啟動用于生成文檔的docle 的類文件。該doclet定義了輸出的內容和格式。如果未使用-doclet選項,則javadoc使用標準doclet生成缺省HTML格式。該類必須 包含start(Root)法。該啟動類的路徑由 -docletpath選項定義。

            -docletpath classpathlist 指定doclet類文件的路徑,該類文件用-doclet選項指定。如果doclet已位于搜索路徑中,則沒有必要使用該選項。

             -1.1 生成具有用Javadoc 1.1生成的文檔的外觀和功能的文檔。也就是說,頁的背景為灰色,用圖像做頁眉,使用bullet列表而不是表格,具有單層目的目錄結構,不包含繼承 API,不使?*** TML框架,并且不支持內部類。該選項還自動將索引分割成每個字母一個文件。如果想要這種外觀,則該選項比javadoc 1.1優越之處等于修正了一些錯誤。

            -sourcepath sourcepathlist
            當將包名傳遞到 javadoc命令中時,指定定位源文件(.java)的搜索路徑。注意只有當用 javadoc命令指定包名時才能使用sourcepath選項 -- 它將不會查找傳遞到javadoc命令中的.java文件。如果省略-sourcepath,則javadoc使用類路徑查找源文件。

            -classpath classpathlist 指定javadoc將在其中查找引用類的路徑 -- 引用類是指帶文檔的類加上它們引用的任何類。Javadoc將搜索指定路徑的所有子目錄。classpathlist可以包括多個路徑,彼此用逗號分隔。

            -bootclasspath classpathlist 指定自舉類所在路徑。它們名義上是Java平臺類。這個bootclasspath是Javadoc將用來查找源文件和類文件的搜索路徑的一部分。在 classpathlist中用冒號(:)分隔目錄。

            -extdirs dirlist 指定擴展類所在的目錄。它們是任何使用Java擴展機制的類。這個 extdirs是Javadoc將用來查找源文件和在文件的搜索路徑的一部分。在dirlist中用冒號(:)分隔目錄。

            -verbose 在javadoc運行時提供更詳細的信息。不使用verbose選項時,將顯示加載源文件、生成文檔(每個源文件一條信息)和排序的信息。verbose選項導致打印額外的信息,指定解析每個java源文件的毫秒數。

            -locale language_country_variant 指定javadoc在生成文檔時使用的環境。

            -encoding name 指定源文件編碼名,例如EUCJIS/SJIS。如果未指定該選項,則使用平臺缺省轉換器。

            -J[flag] 將flag直接傳遞給運行javadoc的運行時系統java。注意在J和flag之間不能有空格。
          標準 Doclet 提供的選項

            -d directory 指定javadoc保存生成的HTML件的目的目錄。省略該選項將導致把文件保存到當前目錄中。其中directory可以是絕對路徑或相對當前工作目錄的相對路徑。

            -use 對每個帶文檔類和包包括一個“用法”頁。該頁描述使用給定類或包的任何 API 的包、類、方法、構造函數和域。對于給定類 C,使用類 C 的任何東西將包括 C 的子類、聲明為 C 的域、返回 C 的方法以及具有 C 類型參數的方法和構造函數。

            -version 在生成文檔中包括 @version 文本。缺省地將省略該文本。

            -author 在生成文檔中包括 @author 文本。

            -splitindex 將索引文件按字母分割成多個文件,每個字母一個文件,再加上一個包含所有以非字母字符開頭的索引項的文件。

            -windowtitle[title] 指定放入 HTML
           


          本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/smile_dyf/archive/2008/09/04/2882247.aspx

          posted @ 2009-12-04 17:12 xzc 閱讀(913) | 評論 (0)編輯 收藏

          轉自:http://www.aygfsteel.com/Todd/archive/2009/09/15/295112.html
          方法一:在初始化時保存ApplicationContext對象
          代碼:
          ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
          ac.getBean("beanId");
          說明:這種方式適用于采用Spring框架的獨立應用程序,需要程序通過配置文件手工初始化Spring的情況。

          方法二:通過Spring提供的工具類獲取ApplicationContext對象
          代碼:
          import org.springframework.web.context.support.WebApplicationContextUtils;
          ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
          ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
          ac1.getBean("beanId");
          ac2.getBean("beanId");
          說明:
          這種方式適合于采用Spring框架的B/S系統,通過ServletContext對象獲取ApplicationContext對象,然后在通過它獲取需要的類實例。

          上面兩個工具方式的區別是,前者在獲取失敗時拋出異常,后者返回null。

          其中 servletContext sc 可以具體 換成 servlet.getServletContext()或者 this.getServletContext() 或者 request.getSession().getServletContext(); 另外,由于spring是注入的對象放在ServletContext中的,所以可以直接在ServletContext取出 WebApplicationContext 對象: WebApplicationContext webApplicationContext = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

          方法三:繼承自抽象類ApplicationObjectSupport
          說明:抽象類ApplicationObjectSupport提供getApplicationContext()方法,可以方便的獲取到ApplicationContext。
          Spring初始化時,會通過該抽象類的setApplicationContext(ApplicationContext context)方法將ApplicationContext 對象注入。

          方法四:繼承自抽象類WebApplicationObjectSupport
          說明:類似上面方法,調用getWebApplicationContext()獲取WebApplicationContext

          方法五:實現接口ApplicationContextAware
          說明:實現該接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 對象。
          Spring初始化時,會通過該方法將ApplicationContext對象注入。


          在web應用中一般用ContextLoaderListener加載webapplication,如果需要在action之外或者control類之外獲取webapplication思路之一是,單獨寫個類放在static變量中,
          類似于:
          public class AppContext {

            
          private static AppContext instance;

            
          private AbstractApplicationContext appContext;

            
          public synchronized static AppContext getInstance() {
              
          if (instance == null) {
                instance 
          = new AppContext();
              }
              
          return instance;
            }

            
          private AppContext() {
              
          this.appContext = new ClassPathXmlApplicationContext(
                  
          "/applicationContext.xml");
            }

            
          public AbstractApplicationContext getAppContext() {
              
          return appContext;
            }
          }

          不過這樣,還是加載了2次applicationcontext,servlet一次,路徑加載一次;覺得不如直接用路徑加載,舍掉servlet加載
          在網上也找了些其他說法:實現ApplicationContextAware,,, 接口,或者servletcontextAware接口,還要寫配置文件。有的竟然要把配置文件里的listener,換成自己的類,這樣純粹多此一舉。不過有的應用不是替換,是在補一個listener,
          我在一版的jpetstore(具體那一版不知道)里發現了這個:
          [web.xml]里
               
              <listener>
                  
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
              
          </listener>
              
              
          <listener>
                  
          <listener-class>com.ibatis.jpetstore.util.SpringInit</listener-class>
              
          </listener>
          其中SpringInit實現接口ServletContextListener

          package com.ibatis.jpetstore.util;

          import javax.servlet.ServletContextEvent;
          import javax.servlet.ServletContextListener;
          import org.springframework.context.ApplicationContext;
          import org.springframework.web.context.WebApplicationContext;
          import org.springframework.web.context.support.WebApplicationContextUtils;


          public class SpringInit implements ServletContextListener {
              

              
          private static WebApplicationContext springContext;
              
              
          public SpringInit() {
                  
          super();
              }
              
              
          public void contextInitialized(ServletContextEvent event) {
                  springContext 
          = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
              }
              

              
          public void contextDestroyed(ServletContextEvent event) {
              }
              
              
          public static ApplicationContext getApplicationContext() {
                  
          return springContext;
              }

              
          }

          在其中的一個bean的構造里SpringInit獲取applicationcontext,代碼:
            public OrderBean() {
              
          this(
                      (AccountService) SpringInit.getApplicationContext().getBean(
          "accountService"),
                      (OrderService) SpringInit.getApplicationContext().getBean(
          "orderService") );
            }

          恩,這種在action,servlet之外的bean里獲取applicationcontext的方法值得參考,應該有用
          posted @ 2009-10-22 18:02 xzc 閱讀(2374) | 評論 (0)編輯 收藏
          • 摘要:在生產中常會遇到需要將數量比較大的表值導入到本地文本文件中. 方法有很多種,比較常用的就是spool命令,本文將為大家介紹這個命令的實現,以及兩種實現方法的對比。
          • 標簽:Oracle  spool  比較

          要輸出符合要求格式的數據文件只需在select時用字符連接來規范格式。比如有如下表

          SQL>; select id,username,password from myuser;//測試表
          1 John       1234
          2 Jack       12345
          3 Rose       2345
          4 Joe        384657
          5 Tom        384655
          6 Jordan     384455

          要輸出符合1,John,1234,這樣的數據格式就用select id||','||username||','||password||',' from myuser這樣的語句。

          SQL>; select id||','||username||','||password||',' from myuser;
          1,John,1234,
          2,Jack,12345,

          寫個下面這樣的腳本就行可以輸出符合要求格式的數據至文件中,不會含有其它不需要東西,只有數據部分。

          --腳本文件名為expmyusr.sql,存數據的文件名為e:\exp.txt

          set echo on            --是否顯示執行的命令內容  
          set feedback off       --是否顯示 *   rows   selected 
          set heading off        --是否顯示字段的名稱
          set verify off         --是否顯示替代變量被替代前后的語句。fil
          set trimspool off      --去字段空格
          set pagesize 1000      --頁面大小
          set linesize 50//linesize設定盡量根據需要來設定,大了生成的文件也大
          define fil= 'e:\exp.txt'
          prompt *** Spooling to &fil
          spool &fil
          select id||','||username||','||'"'||password||'"' from myuser;
          spool off;

           

          --執行過程
          SQL>; @e:\expmyusr.sql
          *** Spooling to e:\exp.txt
          1,John,"1234"
          2,Jack,"12345"
          3,Rose,"2345"
          4,Joe,"384657"
          5,Tom,"384655"
          6,Jordan,"384455"

          檢查可知結果符合要求。

          Oracle SPOOL的兩種方法之對比 

          通常情況下,我們使用SPOOL方法,將數據庫中的表導出為文本文件的時候會采用兩種方法,如下述:

          方法一:采用以下格式腳本 

          set colsep '' ------設置列分隔符
          set trimspool on
          set linesize 120
          set pagesize 2000
          set newpage 1
          set heading off
          set term off
          spool 路徑+文件名
          select * from tablename;
          spool off

          方法二:采用以下腳本

          set trimspool on
          set linesize 120
          set pagesize 2000
          set newpage 1
          set heading off
          set term off
          spool 路徑+文件名
          select col1||','||col2||','||col3||','||col4||'..' from tablename;
          spool off

          比較以上方法,即方法一采用設定分隔符然后由sqlplus自己使用設定的分隔符對字段進行分割,方法二將分隔符拼接在SELECT語句中,即手工控制輸出格式。

          在實踐中,我發現通過方法一導出來的數據具有很大的不確定性,這種方法導出來的數據再由sql ldr導入的時候出錯的可能性在95%以上,尤其對大批量的數據表,如100萬條記錄的表更是如此,而且導出的數據文件狂大。

          而方法二導出的數據文件格式很規整,數據文件的大小可能是方法一的1/4左右。經這種方法導出來的數據文件再由sqlldr導入時,出錯的可能性很小,基本都可以導入成功。

          因此,實踐中我建議大家使用方法二手工去控制spool文件的格式,這樣可以減小出錯的可能性,避免走很多彎路。

          posted @ 2009-09-27 09:20 xzc 閱讀(1344) | 評論 (3)編輯 收藏

           

          General Information
          Note: O/S permissions are those of the user 'Oracle' ... not the schema owner or connected user
          Source {ORACLE_HOME}/rdbms/admin/utlfile.sql
          First Availability 7.3.4
          init.ora Parameters utl_file_dir
          utl_file_dir=c:\oraload
          utl_file_dir=c:\temp
          utl_file_dir=*
          Open Modes
          A Append Text
          AB Append Byte Mode
          R Read Text
          RB Read Byte Mode
          W Write Text
          WB Write Byte Mode
          FCLOSE
          Close A File Opened By UTL_FILE utl_file.fclose(<file_handle>)
          see FOPEN demo
          FCLOSE_ALL
          Close All Files Opened By UTL_FILE utl_file.fclose_all;
          set serveroutput on

          DECLARE
          vInHandle utl_file.file_type;
          vOutHandle utl_file.file_type;
          BEGIN
          vInHandle := utl_file.fopen('ORALOAD', 'test.txt', 'R');
          vOutHandle := utl_file.fopen('ORALOAD', 'out.txt', 'W');

          IF utl_file.is_open(vInHandle) THEN
              utl_file.fclose_all;
              dbms_output.put_line('Closed All');
          END IF;
          END fopen;
          /
          FCOPY
          Copies a contiguous portion of a file to a newly created file utl_file.fcopy (
          location   IN VARCHAR2,
          filename   IN VARCHAR2,
          dest_dir   IN VARCHAR2,
          dest_file IN VARCHAR2,
          start_line IN PLS_INTEGER DEFAULT 1,
          end_line   IN PLS_INTEGER DEFAULT NULL);
          -- demo requires creating directory CTEMP ... see link at bottom of page

          BEGIN
          utl_file.fcopy('ORALOAD', 'dump.txt', 'ORALOAD', 'didit.txt');
          END;
          /
          FFLUSH
          Physically writes pending data to the file identified by the file handle utl_file.fflush (<file_handle>);
          See Write demo
          FGETATTR
          Reads and returns the attributes of a disk file utl_file.fgetattr(
          location    IN VARCHAR2,
          filename    IN VARCHAR2,
          exists      OUT BOOLEAN,
          file_length OUT NUMBER,
          blocksize   OUT NUMBER);
          set serveroutput on

          DECLARE
          ex    BOOLEAN;
          flen NUMBER;
          bsize NUMBER;
          BEGIN
          utl_file.fgetattr('ORALOAD', 'test.txt', ex, flen, bsize);

          IF ex THEN
              dbms_output.put_line('File Exists');
          ELSE
              dbms_output.put_line('File Does Not Exist');
          END IF;
          dbms_output.put_line('File Length: ' || TO_CHAR(flen));
          dbms_output.put_line('Block Size: ' || TO_CHAR(bsize));
          END fgetattr;
          /
          FGETPOS
          Returns the current relative offset position within a file, in bytes utl_file.fgetpos(fileid IN file_type) RETURN PLS_INTEGER;
          See Read-Write demo
          FOPEN
          Open A File For Read Operations utl_file.fopen(
          <file_location IN VARCHAR2>,
          <file_name     IN VARCHAR2>,
          <open_mode     IN VARCHAR2>,
          <max_linesize IN BINARY_INTEGER>)
          RETURN <file_type_package_data_type;
          DECLARE
          vInHandle utl_file.file_type;
          vNewLine VARCHAR2(250);
          BEGIN
          vInHandle := utl_file.fopen('ORALOAD', 'test.txt', 'R');
          LOOP
              BEGIN
                utl_file.get_line(vInHandle, vNewLine);
                dbms_output.put_line(vNewLine);
              EXCEPTION
                WHEN OTHERS THEN
                  EXIT;
              END;
          END LOOP;
          utl_file.fclose(vInHandle);
          END fopen;
          /
          Open A File For Write Operations <file_handle> := utl_file.fopen(<file_location, file_name, 'w')
          FOPEN_NCHAR
          Open a file to read or write a text file in Unicode instead of in the database charset
          FREMOVE
          Delete An Operating System File utl_file.fremove (location IN VARCHAR2, filename IN VARCHAR2);
          BEGIN
          utl_file.fremove('ORALOAD', 'dump.txt');
          END fremove;
          /
          FRENAME
          Rename An Operating System File utl_file.frename (
          location IN VARCHAR2,
          filename IN VARCHAR2,
          dest_dir IN VARCHAR2,
          dest_file IN VARCHAR2,
          overwrite IN BOOLEAN DEFAULT FALSE);
          BEGIN
          utl_file.frename('ORALOAD','test.txt','ORALOAD','x.txt',TRUE);
          END frename;
          /
          FSEEK
          Adjusts the file pointer forward or backward within the file by the number of bytes specified utl_file.fseek (
          fid             IN utl_file.file_type,
          absolute_offset IN PL_INTEGER DEFAULT NULL,
          relative_offset IN PLS_INTEGER DEFAULT NULL);
          See Read-Write demo
          GETLINE
          Read a Line from a file utl_file.getline (
          file     IN FILE_TYPE,
          buffer   OUT VARCHAR2,
          linesize IN NUMBER,
          len      IN PLS_INTEGER DEFAULT NULL);
          See Read demos
          GETLINE_NCHAR
          Same as GETLINE except can be used to read Unicode rather than the database's character set
          GET_RAW
          Reads a RAW string value from a file and adjusts the file pointer ahead by the number of bytes read utl_file.get_raw (
          fid IN utl_file.file_type,
          r   OUT NOCOPY RAW,
          len IN PLS_INTEGER DEFAULT NULL);
          See UTL_MAIL demo
          IS_OPEN
          Returns True If A File Handle Is Open: Otherwise False utl_file.is_open (file IN FILE_TYPE) RETURN BOOLEAN;
          See FCLOSE_ALL Demo
          NEW_LINE
          Writes one or more operating system-specific line terminators to a file utl_file.NEW_LINE (file IN FILE_TYPE, lines IN NATURAL := 1);
          See Read Demo
          PUT
          Writes a string to a file utl_file.put(
          file   IN FILE_TYPE,
          buffer IN VARCHAR2);
          See Write demo
          PUTF
          A PUT procedure with formatting utl_file.putf(
          file   IN FILE_TYPE,
          format IN VARCHAR2,
          [arg1 IN VARCHAR2 DEFAULT NULL,
          . . .
          arg5   IN VARCHAR2 DEFAULT NULL]);
          See Write demo
          PUT_LINE
          Writes a line to a file. Appends an operating system-specific line terminator utl_file.put_line(
          file      IN FILE_TYPE,
          buffer    IN VARCHAR2,
          autoflush IN BOOLEAN DEFAULT FALSE);
          See Read-Write demo
          PUT_NCHAR
          Writes a Unicode string to a file
          PUT_RAW
          Accepts as input a RAW data value and writes the value to the output buffer utl_file.PUT_RAW (
          fid       IN utl_file.file_type,
          r         IN RAW,
          autoflush IN BOOLEAN DEFAULT FALSE);
          See extract_blob Demo
          PUT_LINE_NCHAR
          Writes a Unicode line to a file
          PUTF_NCHAR
          Writes a Unicode string to a file

          from: http://www.psoug.org/reference/utl_file.html

          --End--
          posted @ 2009-09-25 16:18 xzc 閱讀(3143) | 評論 (2)編輯 收藏

          轉:本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/huanghui22/archive/2007/05/03/1595166.aspx


          有些時候我們希望得到指定數據中的前n列,示例如下:

          得到每個部門薪水最高的三個雇員:

          先創建示例表

          create table emp
          as
          select * from scott.emp;

          alter table emp
          add constraint emp_pk
          primary key(empno);

          create table dept
          as
          select * from scott.dept;

          alter table dept
          add constraint dept_pk
          primary key(deptno);

          先看一下row_number() /rank()/dense_rank()三個函數之間的區別

           select emp.deptno,emp.sal,emp.empno,row_number() over (partition by deptno order by sal desc) row_number,  --1,2,3
            rank() over (partition by deptno order by sal desc) rank, --1,1,3
            dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
          結果如下:

          10    5000.00    7839    1    1    1
          10    2450.00    7782    2    2    2
          10    1300.00    7934    3    3    3
          20    3000.00    7788    1    1    1
          20    3000.00    7902    2    1    1
          20    2975.00    7566    3    3    2
          20    1100.00    7876    4    4    3
          20    800.00    7369    5    5    4
          30    2850.00    7698    1    1    1
          30    1600.00    7499    2    2    2
          取每個部門的薪水前三位雇員:

          select t.deptno,t.rank,t.sal from
           (
           select emp.*,row_number() over (partition by deptno order by sal desc) row_number,  --1,2,3
            rank() over (partition by deptno order by sal desc) rank, --1,1,3
            dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
           ) t
          where t.rank<=3
          結果如下:

          10    1    5000.00
          10    2    2450.00
          10    3    1300.00
          20    1    3000.00
          20    1    3000.00
          20    3    2975.00
          30    1    2850.00
          30    2    1600.00
          30    3    1500.00
          如果想輸出成deptno  sal1   sal2   sal3這種類型的格式
          步驟一(decode):

          select t.deptno,decode(row_number,1,sal) sal1,decode(row_number,2,sal) sal2,decode(row_number,3,sal) sal3 from
           (
           select emp.*,row_number() over (partition by deptno order by sal desc) row_number,  --1,2,3
            rank() over (partition by deptno order by sal desc) rank, --1,1,3
            dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
           ) t
          where t.rank<=3

          結果如下:

          10    5000       
          10                  2450   
          10                             1300
          20    3000       
          20                  3000   
          20                              2975
          30    2850       
          30                 1600   
          30                             1500
          步驟二(使用聚合函數去除null,得到最終結果):

          select t.deptno,max(decode(row_number,1,sal)) sal1,max(decode(row_number,2,sal)) sal2,max(decode(row_number,3,sal)) sal3 from
           (
           select emp.*,row_number() over (partition by deptno order by sal desc) row_number,  --1,2,3
            rank() over (partition by deptno order by sal desc) rank, --1,1,3
            dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
           ) t
          where t.rank<=3
          group by t.deptno
          結果如下:

          10    5000    2450    1300
          20    3000    3000    2975
          30    2850    1600    1500

           

          posted @ 2009-09-07 16:45 xzc 閱讀(418) | 評論 (0)編輯 收藏

          24/05/2005 14:37 FP 在數據倉庫中的轉換和裝載過程中,經常會使用MERGE語句,這里簡單總結一下。


          MERGE語句是Oracle9i新增的語法,用來合并UPDATE和INSERT語句。通過MERGE語句,根據一張表或子查詢的連接條件對另外一張表進行查詢,連接條件匹配上的進行UPDATE,無法匹配的執行INSERT。這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高于INSERT+UPDATE。
          下面看個具體的例子:
          SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;
          表已創建。
          SQL> CREATE TABLE T1 AS
          2 SELECT ROWNUM ID, OWNER, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE
          3 FROM DBA_TABLES;
          表已創建。
          SQL> MERGE INTO T1 USING T
          2 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
          3 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
          4 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);
          6165 行已合并。
          SQL> SELECT ID, OWNER, OBJECT_NAME, OBJECT_TYPE FROM T
          2 MINUS
          3 SELECT * FROM T1;
          未選定行
          MERGE語法其實很簡單,下面稍微修改一下例子。
          SQL> DROP TABLE T;
          表已丟棄。
          SQL> DROP TABLE T1;
          表已丟棄。
          SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;
          表已創建。
          SQL> CREATE TABLE T1 AS SELECT ROWNUM ID, OWNER, TABLE_NAME FROM DBA_TABLES;
          表已創建。
          SQL> MERGE INTO T1 USING T
          2 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
          3 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
          4 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);
          MERGE INTO T1 USING T
          *
          ERROR 位于第 1 行:
          ORA-30926: 無法在源表中獲得一組穩定的行
          這個錯誤是使用MERGE最常見的錯誤,造成這個錯誤的原因是由于通過連接條件得到的T的記錄不唯一。最簡單的解決方法類似:
          SQL> MERGE INTO T1
          2 USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID FROM T GROUP BY OWNER, OBJECT_NAME) T
          3 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
          4 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
          5 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);
          5775 行已合并。
          另外,MERGE語句的UPDATE不能修改用于連接的列,否則會報錯,詳細信息可以參考:
          http://blog.itpub.net/post/468/14844

          ===============================================================

          ref: http://tomszrp.itpub.net/post/11835/263865

          在Oracle 10g之前,merge語句支持匹配更新和不匹配插入2種簡單的用法,在10g中Oracle對merge語句做了增強,增加了條件選項和DELETE操作。下面我通過一個demo來簡單介紹一下10g中merge的增強和10g前merge的用法。

           

          參考Oracle 的SQL Reference,大家可以看到Merge Statement的語法如下:
          MERGE [hint] INTO [schema .] table [t_alias] USING [schema .]
          { table | view | subquery } [t_alias] ON ( condition )
          WHEN MATCHED THEN merge_update_clause
          WHEN NOT MATCHED THEN merge_insert_clause;

          下面我在windows xp 下10.2.0.1版本上做一個測試看看

          SQL> select * from v$version;
          BANNER
          ----------------------------------------------------------------
          Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
          PL/SQL Release 10.2.0.1.0 - Production
          CORE    10.2.0.1.0      Production
          TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
          NLSRTL Version 10.2.0.1.0 - Production
          SQL>
          一、創建測試用的表
          SQL> create table subs(msid number(9),
          2                    ms_type char(1),
          3                    areacode number(3)
          4                    );
          表已創建。
          SQL> create table acct(msid number(9),
          2                    bill_month number(6),
          3                    areacode   number(3),
          4                    fee        number(8,2) default 0.00);
          表已創建。
          SQL>
          SQL> insert into subs values(905310001,0,531);
          已創建 1 行。
          SQL> insert into subs values(905320001,1,532);
          已創建 1 行。
          SQL> insert into subs values(905330001,2,533);
          已創建 1 行。
          SQL> commit;
          提交完成。
          SQL>
           
          二、下面先演示一下merge的基本功能
          1) matched 和not matched clauses 同時使用
          merge into acct a
          using subs b on (a.msid=b.msid)
          when MATCHED then
          update set a.areacode=b.areacode
          when NOT MATCHED then
          insert(msid,bill_month,areacode)
          values(b.msid,'200702',b.areacode);
          2) 只有not matched clause,也就是只插入不更新
          merge into acct a
          using subs b on (a.msid=b.msid)
          when NOT MATCHED then
          insert(msid,bill_month,areacode)
          values(b.msid,'200702',b.areacode);
          3) 只有matched clause, 也就是只更新不插入
          merge into acct a
          using subs b on (a.msid=b.msid)
          when MATCHED then
          update set a.areacode=b.areacode
          Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
          Connected as study
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when MATCHED then
          4          update set a.areacode=b.areacode
          5     when NOT MATCHED then
          6          insert(msid,bill_month,areacode)
          7          values(b.msid,'200702',b.areacode);
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905320001     200702      532       0.00
          905330001     200702      533       0.00
          905310001     200702      531       0.00
          SQL> insert into subs values(905340001,3,534);
          1 row inserted
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905340001 3            534
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when NOT MATCHED then
          4          insert(msid,bill_month,areacode)
          5          values(b.msid,'200702',b.areacode);
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905320001     200702      532       0.00
          905330001     200702      533       0.00
          905310001     200702      531       0.00
          905340001     200702      534       0.00
          SQL> update subs set areacode=999;
          4 rows updated
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905340001 3            999
          905310001 0            999
          905320001 1            999
          905330001 2            999
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905320001     200702      532       0.00
          905330001     200702      533       0.00
          905310001     200702      531       0.00
          905340001     200702      534       0.00
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when MATCHED then
          4          update set a.areacode=b.areacode;
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905320001     200702      999       0.00
          905330001     200702      999       0.00
          905310001     200702      999       0.00
          905340001     200702      999       0.00
          SQL>
           
          三、10g中增強一:條件操作
          1) matched 和not matched clauses 同時使用
          merge into acct a
          using subs b on (a.msid=b.msid)
          when MATCHED then
          update set a.areacode=b.areacode
          where b.ms_type=0
          when NOT MATCHED then
          insert(msid,bill_month,areacode)
          values(b.msid,'200702',b.areacode)
          where b.ms_type=0;
          2) 只有not matched clause,也就是只插入不更新
          merge into acct a
          using subs b on (a.msid=b.msid)
          when NOT MATCHED then
          insert(msid,bill_month,areacode)
          values(b.msid,'200702',b.areacode)
          where b.ms_type=0;
          3) 只有matched clause, 也就是只更新不插入
          merge into acct a
          using subs b on (a.msid=b.msid)
          when MATCHED then
          update set a.areacode=b.areacode
          where b.ms_type=0;
          Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
          Connected as study
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when MATCHED then
          4          update set a.areacode=b.areacode
          5          where b.ms_type=0
          6     when NOT MATCHED then
          7          insert(msid,bill_month,areacode)
          8          values(b.msid,'200702',b.areacode)
          9          where b.ms_type=0;
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905310001     200702      531       0.00
          SQL> insert into subs values(905360001,0,536);
          1 row inserted
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905360001 0            536
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when NOT MATCHED then
          4          insert(msid,bill_month,areacode)
          5          values(b.msid,'200702',b.areacode)
          6          where b.ms_type=0;
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905310001     200702      531       0.00
          905360001     200702      536       0.00
          SQL> update subs set areacode=888 where ms_type=0;
          2 rows updated
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905360001 0            888
          905310001 0            888
          905320001 1            532
          905330001 2            533
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905310001     200702      531       0.00
          905360001     200702      536       0.00
          SQL>
          SQL> merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when MATCHED then
          4          update set a.areacode=b.areacode
          5          where b.ms_type=0;
          Done
          SQL> select * from acct;
          MSID BILL_MONTH AREACODE        FEE
          ---------- ---------- -------- ----------
          905310001     200702      888       0.00
          905360001     200702      888       0.00
          SQL>
          四、10g中增強二:刪除操作
          An optional DELETE WHERE clause can be used to clean up after a
          merge operation. Only those rows which match both the ON clause
          and the DELETE WHERE clause are deleted.
          merge into acct a
          using subs b on (a.msid=b.msid)
          when MATCHED then
          update set a.areacode=b.areacode
          delete where (b.ms_type!=0);
          SQL> select * from subs;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL> select * from acct;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905310001 0            531
          905320001 1            532
          905330001 2            533
          SQL>
          SQL>  merge into acct a
          2       using subs b on (a.msid=b.msid)
          3     when MATCHED then
          4          update set a.areacode=b.areacode
          5          delete where (b.ms_type!=0);
          Done
          SQL> select * from acct;
          MSID MS_TYPE AREACODE
          ---------- ------- --------
          905310001 0            531
          SQL>
          更為詳盡的語法,請參考Oracle SQL Reference手冊!
          
          posted @ 2009-08-25 21:42 xzc 閱讀(292) | 評論 (0)編輯 收藏

           
          awk處理文本總結 - Alex.Wang            2008-2-19 15:55

          作為技術支持工程我們最最經常的工作就是經常碰到要處理文本文件,不管是什么數據庫最后都可以導成文本,我們就可以對他進行處理了,這樣即使你不是對所有數據庫操作都很熟悉也可以對他的數據進行處理了。

          我們必須的工具有兩個一個是shell一個是awk,awk對于處理文本文件是最最適合的掌握了awk我們就可以很方便的處理文本文件再借助一些shell命令我們可以很方便得到自己想要的結果。現在從簡單的例子來總結一下我覺得會經常碰到的問題。


          --------------------------------------------------------------------------------

          awk入門篇
           awk入門,文本內容example1.txt.
             
          user1 password1 username1 unit1 10
          user2 password2 username2 unit2 20
          user3 password3 username3 unit3 30 

           

          在unix環境中我們可以使用一下命令來打印出第一列
             
          [root@mail awk]# awk '{print $1}' example1.txt

              得到的結果是如下,解釋一下"'{" 單引號大括號包含awk語句是為了和shell 命令區別,$1的意思就是文本文件的第一列,正常的awk命令跟隨-F參數指定間隔符號,如果是空格或tab鍵就可以省略了。   
          user1
          user2
          user3 

          [root@mail awk]# awk '{if($5>20) {print $1}}' example1.txt

                  這行命令和上一行比較增加了“if($5>20)”,得到的結果是

          user3

          這個if語句就沒有必要更詳細的解釋了吧!就是第5列大于20的顯示出滿足條件的第一列

          [root@mail awk]# awk '{if($5>20 || $5==10) {print $1}}' example1.txt

          user1
          user3

          在來一個初級的又增加了一個“if($5>20 || $5==10)”    做邏輯判斷邏輯判斷的三個“|| && !” 或、與、非三個可以任意加到里面,這個語句的意思是如果第5列大于20或者等于10的都顯示處理,在我們的工作中可能有用戶會要求找出所有空間大于多少的或者是空間等于多少的賬戶然后再做批量修改。

          if是awk循環中的一個還有其他很多,man awk可以看到,
             Control Statements
                 The control statements are as follows:

                        if (condition) statement [ else statement ]
                        while (condition) statement
                        do statement while (condition)
                        for (expr1; expr2; expr3) statement
                        for (var in array) statement
                        break
                        continue
                        delete array[index]
                        delete array
                        exit [ expression ]
                        { statements }


          學習awk可以經常使用一下man awk 可以看到所有的函數和使用方法。   

          了解每個符號的意義我們才能更好的使用awk,最開始先記住幾個命令知道他可實現的結果我們慢慢的再去理解。


          --------------------------------------------------------------------------------

          awk中級篇
          這里順便介紹一下vi的一個替換命令,現在我們要把example1.txt文本里的空格都替換為“:”冒號這里在vi里使用的命令就是:

          %s/ /:/g     

          這個命令對于使用vi的人來說是用得最多的。我們現在做了一個新的文件example2.txt。

          user1:password1:username1:unit1:10
          user2:password2:username2:unit2:20
          user3:password3:username3:unit3:30

          現在我們來做一個awk腳本,之前都是在命令行操作,實際上所有的操作在命令行上是可以都實現的,已我們最經常使用的批量添加用戶來開始!

          script1.awk

          #!/bin/awk -f   # 當文件有可執行權限的時候你可以直接執行
                          # ./script1.awk example2.txt
                          # 如果沒有以上這行可能會出現錯誤,或者
                          # awk -f script1.awk example2.txt 參數f指腳本文件

          BEGIN {         # “BEGIN{”是awk腳本開始的地方
              FS=":";     # FS 是在awk里指分割符的意思
          }

          {                                # 接下來的“{” 是內容部分
                print "add {";             # 以下都是使用了一個awk函數print
                print "uid=" $1;
                print "userPassword=" $2;
                print "domain=eyou.com" ;
                print "bookmark=1";
                print "voicemail=1";
                print "securemail=1"
                print "storage=" $5;
                print "}";
                print ".";
          }                               # “}”    內容部分結束
          END {                           # “END{” 結束部分
              print "exit";
          }

          執行結果
          [root@mail awk]# awk -f script1.awk example2.txt
          add {
          uid=user1
          userPassword=password1
          domain=eyou.com
          bookmark=1
          voicemail=1
          securemail=1
          storage=10
          }
          .              
          .
          .
          .
          .
          .
          exit

          文本操作就是更方便一些。

          下面給兩個返回效果一樣的例子
          [root@mail awk]# awk -F: '{print $1"@"$2}' example2.txt
          [root@mail awk]# awk -F: '{printf "%s@%s\n",$1,$2}' example2.txt

          user1@password1

          這里的區別是使用print 和printf的區別,printf格式更自由一些,我們可以更加自由的指定要輸出的數據,print會自動在行尾給出空格,而printf是需要給定" \n"的,如果感興趣你可以把“\n”去掉看一下結果。%s代表字符串%d 代表數字,基本上%s都可以處理了因為在文本里一切都可以看成是字符串,不像C語言等其他語言還要區分數字、字符、字符串等。

          awk還有一些很好的函數細細研究一下還是很好用的。


          這次碰到了一個問題客戶有一個用戶列表,大概有2w用戶,他有一個有趣的工作要做,就是把每個賬戶目錄放到特定的目錄下,例如13910011234這個目錄要放到139/10/這個目錄下,從這里可以看出規律是手機號碼的前三位是二級目錄名,手機的第3、4為是三級目錄名,我們有的就只有一個用戶列表,規律找到了我們現在開始想辦法處理吧。

          example3.txt

          13910011234     
          15920312343
          13922342134
          15922334422
          ......

          第一步是要找到一個方法來吧,就是要把每一個手機號分開,最初可能你就會想到這個也沒有任何間隔,我們怎么用awk分開他們呢?說實話最初我也考慮了20多分鐘,后來想起原來學習python的時候有split函數可以分就想找找awk里是不是有類似的函數,man awk 發現substr 這個函數子串,

          [root@mail awk]# awk '{print substr($1,1,3)}'  example3.txt

          [root@mail awk]# awk '{printf "%s/%s\n",substr($1,1,3),substr($1,4,2)}'  example3.txt

          [root@mail awk]# awk '{printf "mv %s %s/%s\n",$1,substr($1,1,3),substr($1,4,2)}'  example3.txt

          以上的兩步的返回自己做一下,最后我們就得到了我們想要的結果。

          mv 13910011234 139/10
          mv 15920312343 159/20
          mv 13922342134 139/22
          mv 15922334422 159/22

          把這部分輸出拷貝到一個shell腳本里,在數據當前目錄下執行就可以了!

          substr(s, i [, n])      Returns  the at most n-character substring of s
                                         starting at i.  If n is omitted, the rest of  s
                                         is used.
                                        
          substr函數解釋,s代表我們要處理的字符串,i 是我們從這個字符串的第幾個位置上開始,n 是我們從開始的位置取多少個字符。多看看man英文也會有所提高的。                              

          awk有很多有趣的函數如果感興趣可以自己去查查看,
          man awk
          String Functions  字符串函數,舉幾個覺得常用的函數
              length([s])             Returns  the  length  of  the  string s, or the
                                         length of $0 if s is not supplied.
              length 你可以得到字符串的長度,這個是比較常用的一個函數                         
              split(s, a [, r])       Splits the string s into the  array  a  on  the
                                         regular expression r, and returns the number of
                                         fields.  If r is omitted, FS is  used  instead.
                                         The   array  a  is  cleared  first.   Splitting
                                         behaves   identically   to   field   splitting,
                                         described above.    
                                        
                  tolower(str)            Returns  a copy of the string str, with all the
                                         upper-case  characters  in  str  translated  to
                                         their  corresponding  lower-case  counterparts.
                                         Non-alphabetic characters are left unchanged.
                                        
                  toupper(str)            Returns a copy of the string str, with all  the
                                         lower-case  characters  in  str  translated  to
                                         their  corresponding  upper-case  counterparts.
                                         Non-alphabetic characters are left unchanged.
                                                                                              Time Functions  時間函數,我們最最常用到的是時間戳轉換函數
                                                                                            
          strftime([format [, timestamp]])
                           Formats  timestamp  according to the specification in format.
                           The timestamp should be of the same form as returned by  sys-
                           time().   If timestamp is missing, the current time of day is
                           used.  If format is missing, a default format  equivalent  to
                           the output of date(1) is used.  See the specification for the
                           strftime() function in ANSI C for the format conversions that
                           are  guaranteed  to be available.  A public-domain version of
                           strftime(3) and a man page for it come  with  gawk;  if  that
                           version  was  used to build gawk, then all of the conversions
                           described in that man page are available to gawk.                                                                                  
                                                                                            
          這里舉例說明時間戳函數是如何使用的

          [root@ent root]# date +%s | awk '{print strftime("%F %T",$0)}'
          2008-02-19 15:59:19        

          我們先使用date命令做一個時間戳,然后再把他轉換為時間                                                                                             
          還有一些我們現在可能不經常用到的函數,詳細內容man awk 自己可以看一下。
           Bit Manipulations Functions   二進制函數
           Internationalization Functions  國際標準化函數
           
           USER-DEFINED FUNCTIONS      用戶也可以自己定義自己的函數,感興趣自己可以再深入研究一下。
           
           For example:

                        function  f(p, q,     a, b)   # a and b are local
                        {
                             ...
                        }

                        /abc/     { ... ; f(1, 2) ; ... }
           DYNAMICALLY LOADING NEW FUNCTIONS  動態加載新函數,這個可能就更高級一些了!


          --------------------------------------------------------------------------------

           awk高級篇
           
           不管學習任何語言,我們學到的都是工具,工具知道的越多,我們做起工作來就越方便,但是工具在你的手里并不一定能造出好的產品,編輯腳本和編程序也是一樣的重要的是算法,別人不知道怎么處理的問題你要知道如何處理。這才能證明你比別人更高,工具只要你慢慢練習都會使用。
           
              下面給大家一個我認為是比較高級的問題了,感興趣的可以自己再想想更好的解決辦法。問題是這樣的我們有一個從ldap里導出的文件,它都是一行一個字段來說明的,每個用戶的數據是已空行分割的。我們必須把對應的uid 和userPassword找出來而且是對應的。
             
              例子:example4.txt
             
          dn: uid=cailiying,domain=ccc.com.cn,o=mail.ccc.com.cn
          uid: cailiying
          userPassword:: e21kNX0zREl4VEIwODBJdXZkTnU3WFFtS3lRPT0=
          letters: 300
          quota: 100

          dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
          userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
          letters: 300
          quota: 100
          uid: chenzheng
          domain: cqc.com.cn

          dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
          userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
          letters: 300
          quota: 100

          dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
          userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
          letters: 300
          quota: 100
          uid: chenzheng
          domain: cqc.com.cn
                                                                                              處理這個文本我們需要考慮的問題是:
          1 uid  和userPassword 并不是每一個段落里都有
          2 在每一段里面uid和userPassword 先后順序是隨機的
          3 有的段落里可能只有uid 或者只有userPassword

          從文本上分析可以看出必須使用的間隔符號,一個是空行,一個是冒號。
          冒號我們awk -F:就可以了,不過空行我們不好判斷現在想到length()這個函數,在unix里空行最多只有一個\n字符,如果一行字符數小于2我們判斷為空行,好現在間隔符號問題解決,空行只能通過循環來實現對空行的判斷。                                        

          現在碰到的另外一個問題是我們的某個段里的信息是不完全的,我們就要放棄這段這兒如何來做,就是要做兩個標記變量u 和 p  再做一個循環如果u  和  p 同事滿足我們才輸出結果下面的awk腳本就是通過這個思考來解決ldif文本的處理的!

          # 此腳本的目的是方便我們以后導ldap的其他郵件的數據,
          # 我們之前使用slapdcat -l 導出所有信息,然后我們需要
          # 整理出uid  password , 這里的設置都是默認以":" 間隔的
          # 例slapcat -l user.ldif  如果想得到一份uid 和userPassword 對應的文件,
          # 修改username = "dn"; password = "userpassword"; awk -f ldap2txt.awk user.ldif | grep uid | more  可以查看結果 (有可能是多域的郵件)
          # 如果想得到domain 所對應的密碼,修改username = "dn"; password = "userpassword";  運行 awk -f ldap2txt.awk user.ldif |grep domain | more


          #!/bin/awk -f
          # File name: ldap2txt.awk

          BEGIN {
                  FS = ":";
                  username = "uid";
                  password = "userPassword";
          }

          {

                  if(length($0) == 0 )
                  {
                          if (name != "u"  &&  pword != "p")
                          {
                                  printf ("%s:%s\n", name,pword);
                                  name = "u";
                                  pword = "p";
                          }
                  }

                  else 
                  {
                          if ($1 == username)
                          {
                          name = "u";
                          name = $0;
                          }
                          else if($1 == password)
                          {
                          pword = "p";
                          pword = $0;
                          }
                  }
          }
          END {

          }

          實際上對于學習語言首先是熟悉一些常用的函數,然后就是試著去解決別人解決過的問題,然后自己再思考一下是不是有更好,速度更快的解決辦法,實際上大部分的程序員都是在重復的使用著別人好的解決辦法,把別人的方法轉變為自己的方法,就是反復練習解決不同的問題,思考更好的方法!


          本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/blackbillow/archive/2009/01/21/3847425.aspx

          posted @ 2009-08-21 14:09 xzc 閱讀(381) | 評論 (0)編輯 收藏
          posted @ 2009-08-17 18:01 xzc 閱讀(316) | 評論 (0)編輯 收藏
          僅列出標題
          共32頁: First 上一頁 15 16 17 18 19 20 21 22 23 下一頁 Last 
          主站蜘蛛池模板: 襄汾县| 闻喜县| 江西省| 武汉市| 陇西县| 祁门县| 资溪县| 龙井市| 南乐县| 兴安县| 拉孜县| 嘉义市| 读书| 外汇| 达尔| 镇巴县| 营山县| 色达县| 云安县| 龙游县| 鞍山市| 新闻| 大英县| 磐石市| 志丹县| 铁岭县| 惠来县| 报价| 大余县| 绥德县| 高平市| 井研县| 汽车| 泰州市| 普兰县| 香港| 庄浪县| 高邮市| 望江县| 铁岭市| 阿城市|