|
awkを使ってファイルからある部分のデータを取り出そうとしています。 ファイルの内容 ---------------------------------- ---------------------------------------- Tue Jul 31 09:00:00 Jst 2007 xxxxxx xxxxxx xxxxxx xxxxxx Tue Jul 31 09:00:00 Jst 2007 ---------------------------------------- Tue Jul 31 09:10:00 Jst 2007 xxxxxx xxxxxx xxxxxx xxxxxx Tue Jul 31 09:10:00 Jst 2007 ---------------------------------------- Wed Aug 1 09:00:00 JST 2007 xxxxxx xxxxxx xxxxxx Wed Aug 1 09:00:00 JST 2007 該当の曜日、月、日から始まる行以降から 最終行まですべてを取り出そうとしているのですが、 awkで上手くいきません。 以下の様なエラーがでて上手くいきません。 どうすればよいのでしょうか。 awk: syntax error near line 1 awk: bailing out near line 1 シェルの内容 ----------------------------------------- #!/bin/sh LOG_FILE="/tmp/kekka.log" #DATE=`date "+%a %b %e"` DATE=`date +%C | cut -c 1-10` awk -v DAY=$DATE'/^DATE/,/\\r/ {print $0}' ${LOG_FILE} exit 0 |
|
UNIXの環境変数のLANGに使用する言語の指定に 「japanese」があるのですが、これは、日本語 が使えるのですか。それとも日本語のSJISが 使えるのでしょう。 また、UNIXのOSがどのコードなのかどこを見れば わかるのでしょうか。 また、EBCDICコードがあるのですが、これを使うには どうしたらよいのでしょうか。 |
|
>>4820 べた > awk -v DAY=$DATE'/^DATE/,/\\r/ {print $0}' ${LOG_FILE} まずは % sh -x スクリプト名 などとして、意図どおりの引数を渡せているか確認しましょう。この場合は awk -v DAY=20/^DATE/,/\\r/ {print $0} a.dat と表示されますので、意図通りではないはずです。 具体的には以下の問題があります。 - 20 はおそらく希望する値ではない - 20 の後に空白がない。 - DATE の中にある変数でパターンマッチするのではなく、"DATE" という文字列を 探すようになっている。 - DAY と DATE の誤記。 >>4821 なし > UNIXの環境変数のLANGに使用する言語の指定に > 「japanese」があるのですが、これは、日本語 > が使えるのですか。それとも日本語のSJISが > 使えるのでしょう。 一般的には japanese は ja_JP.eucJP・ja_JP.PCK (Shift_JIS)・ja_JP.utf-8 などのエイリアスであることが多いように思います。実際にどのエイリアスで あるかは OS やバージョンによるでしょう。 > また、UNIXのOSがどのコードなのかどこを見ればわかるのでしょうか。 OS により異なると思います。env コマンドで何か出てくるかもしれません。 > また、EBCDICコードがあるのですが、これを使うにはどうしたらよいのでしょうか。 例えば dd コマンドで ASCII に変換できます。商用のアプリケーションも いくつか出ているようです。 |
|
UNIX の部屋に ファイル制限まとめ http://x68000.q-e-d.net/~68user/unix/pickup?%A5%D5%A5%A1%A5%A4%A5%EB%C0%A9%B8%C2%A4%DE%A4%C8%A4%E1 を追加しました。 |
|
>>68user ありがとうございます。 >% sh -x スクリプト名 で確認してみました。 DAYとDATEは誤記ですが、DAYに直しましたが結果は同じでした。 awk -v DAY=$DATE'/^DAY/,/\\r/ {print $0}' ${LOG_FILE} パターンマッチングのところが、引数で渡した値ではなく、 ”DAY”という文字列でした。(文字列と言い切れるのかどうか。?) |
|
>>4824 べた まずはコマンドラインから awk を叩いて、正しい結果を取得できるように なるところから始めましょう。シェルスクリプトはその後。 あと >>4822 68user > 具体的には以下の問題があります。 を直さないと動きません。念のため。 |
|
>>4825 68user 色々とありがとうございます。 試してみます。 |
|
>>4825 68user やはり、「^」を指定しているので、行の先頭が、DAYという 文字列から始まっているのを探していました。 試しにファイルの方を修正し、日付を「DAY Aug 2」としたところ 表示されました。 マッチングのところに、変数を展開できないのでしょうか。 nawk -v DAY="Fri Aug 10" '/^DAY/,/\\r\\n/ {print $0}' /tmp/kekka_log.log |
|
>>4822 68user 返事遅れてすみません。 ありがとうございます。 |
|
>>4827 べた 変数展開は $n ~ VAR と書きます。 で、/\\r\\n/ ですが、これうまく動きますか? awk はよくわかりませんが、 マッチしてないと思います。 なので、DAY から ------ までを見るようにして、 awk -v DAY="Fri Aug 10" '$0 ~ DAY,/^--*$/ {print}' か awk -v DAY="Fri Aug 10" 'BEGIN{skip=1} $0 ~ DAY {skip=1;print $0} /^--*$/ {skip=0} skip==1 {print} ' あたりがいいんじゃないですかね。 なお、行頭の日付だけ見るなら、DAY="^Fri Aug 10" です。 |
|
「リダイレクト」についての説明の中の 『「リダイレクトは右に書いたものから順に評価されるから」は間違いである。』 のくだりが分かりやすくてつい書き込んでしまいました。 他のサイトは上記のような説明で終わっている所があったのですが、 なんとなく「ん?」と違和感が残ってました。 で、このサイトの内容ですっきりです。ありがとうございました。 ドメインも素敵です(笑) |
|
>>4830 通りすがり ありがとうございます。ついでなので書いておくと、先頭に書いてもいいです。 >/dev/null 2>&1 ls foo.txt |
|
>>4829 68user ありがとうございます。 変数の展開ができました。 「'$0 ~ DAY」 の使い方は知りませんでした。 >で、/\\r\\n/ ですが、これうまく動きますか? awk はよくわかりませんが、 >マッチしてないと思います。 ファイルの最後まで見るというつもりでした。 EOFがこの表記でいいのかさなかですが。? 多分、ファイルの最後まで走査し、終了しているのではないかと。 >awk -v DAY="Fri Aug 10" 'BEGIN{skip=1} $0 ~ DAY {skip=1;print $0} /^--*$/ {skip=0} skip==1 {print} ' 日付が二行でます。 Fri Aug 10 ・・・ Fri Aug 10 ・・・ **** **** **** Fri Aug 10 ・・・ Fri Aug 10 ・・・ 見たいになります。 |
|
>>4832 べた > ファイルの最後まで見るというつもりでした。 その挙動でよいのであれば、問題ないと思います (実質機能していないと 思うので、書き方としてはまずいですが)。 > 日付が二行でます。 print $0 を削除するなどしてください。 |
|
>>4833 68user お礼遅れてすみません。 ありがとうございました。 |
|
前にも同じ質問をしたのですが、 findの検索で、指定ディレクトリ(カレントディレクトリ)内の ファイルだけを検索し、-mtimeを指定して、30日前のファイルを 削除しようとしています。 配下のディレクトリを検索しないよう、-prune を指定して、まずは、 以下のようにしたのですが、”*.csv”以外が表示されていまいます。 find /home/DATA/backup -name '*.csv' -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune -o -print と実行すると、 カレントディレクトリと、「*.csv」以外のファイルが表示されます。 find /home/DATA/backup -name '*.csv' -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune -o -mtime +30 と実行すると、 表示されるのですが、どこのディレクトリを検査した結果かわからない状態でして、 確認と実際は、rm を指定してファイルを削除するで、「-exec ls -l {} \;」 をして表示してみたのですが、 find /home/DATA/backup -name '*.csv' -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune -o -mtime +30 -exec ls -l {} \; と実行すると、 何も表示されません。 find /home/DATA/backup -name '*.csv' -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune -o -mtime +30 -print と実行すると、 何も表示されません。 正しく、結果が表示されるように、 最終的には、30日前とか、90日前のファイルが削除できるように したいのですが、どのようにすればよいか、 教えてください。 |
|
>>4836 べた > find /home/DATA/backup -name '*.csv' -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune -o -print > と実行すると、 > カレントディレクトリと、「*.csv」以外のファイルが表示されます。 この結果がすでにマズいんですよね? 前回のわたしの回答 >>4763 68user は的外れだったような気がします。最終的には以下のようになるのではないかと思います。 % find /home/DATA/backup -name '*.csv' -mtime +30 -exec ls -l {} \; -o -name everyday -prune -o -name monthly -prune -o -name tmp -prune -o -name work -prune 構造としては ・[ファイル名が *.csv] AND [mtime が +30] AND [-exec ls -l] OR ・[ファイル名が everyday] AND [-prune] OR ・[ファイル名が monthly] AND [-prune] OR (略) となります。 ただし -exec や -prune は常に真で、コマンドを実行する・ディレクトリを下降しない という副作用を発生させるのが主目的ですので、より平易に書くと ・[ファイル名が *.csv] AND [mtime が +30] なら [-exec ls -l] を実行 OR ・[ファイル名が everyday] なら [-prune] で下降抑止 OR ・[ファイル名が monthly] なら [-prune] で下降抑止 OR (略) となります。なお、ここでの OR は、左辺が真なら右辺は評価しない、 という意味です。また、OR の各要素の順序を入れ替えても、このケース では問題ありません (*.csv と everyday が両方真になることはないので)。 典型的な -prune の使い方をまとめると以下のようになると考えます。 - 特定のディレクトリ以外について何か (-print) を行う ⇒ find . -name hoge -prune -o -print - 特定のパターンのファイルに何か (-ls) を行うが、特定ディレクトリ以下は除外する ⇒ find . -name \*.csv -ls -o -name hoge -prune - 特定のパターンのファイルに何か (-print) を行うが、特定ディレクトリだけは 除外する。ただし特定のパターンにも特定のディレクトリにも一致しない場合は、 別の何かを行う (-ls)。 ⇒ find . -name \*.csv -print -o -name hoge -prune -o -ls |
|
>>4837 68user ありがとうございます。 返事遅れてすみません。 一度、内容を読んで、確認してみます。 それで、再度、質問します。 |
|
>>4837 68user ありがとうございます。 期待した結果が得られました。 |