• ベストアンサー

" ls -l " から、指定縦列の中から、grepする方法

SunOS 5.8 sun4u sparc UltraAX-i2 > ls -l -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-1.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-2.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-3.txt -rw-r--r-- 1 root other 100 5月 11日 00:00 abc-11.txt -rw-r--r-- 1 root other 100 1月 12日 00:00 abc-12.txt -rw-r--r-- 1 root other 100 1月 13日 00:00 abc-13.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-5.txt -rw-r--r-- 1 root other 100 5月 1日 00:00 abc-6.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-7.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-51.txt -rw-r--r-- 1 root other 100 1月 1日 00:00 abc-61.txt -rw-r--r-- 1 root other 100 5月 1日 00:00 abc-71.txt ここから、" 5月 " のファイルのみを標準出力したいのですが、 日本語環境の不備から " ls -l | grep 5月 " のコマンドは刎ねられます。 ですので、策としては、以下のように ls -l ↓ 6列目(月列)を指定。 ↓ 5 を grep しなさい。 このように(sort +5)のような感じで、パイプをつなげたようなコマンドを用意したいのですが、 その機能が見つかりません。詳しい方、教えて下さい。 csh (bash使用可能) egrep,fgrep使用可能

質問者が選んだベストアンサー

  • ベストアンサー
  • k0y
  • ベストアンサー率100% (1/1)
回答No.7

#6の続きです ls -ltr|perl -lane 'print $_ if $F[5]=~/^5[^0-9]/' でいかがでしょうか。 日本語環境がないため確認できていませんが... 今回「[^0-9]」を追加していますが、5[^0-9]で 「5から始まって次が数字でない場合」となります。 「[^~]」で「~以外」になり「0-9」で数字を表します。 本来は「5月」などとしたいのですが日本語を入れると怖いので(?) このような形を取っております。 これによって、おそらく ls -ltr|perl -lane 'print $_ if $F[5]=~/^1[^0-9]/' で、1月のファイルのみ抽出できるはずです。

Piranha
質問者

お礼

http://oshiete1.goo.ne.jp/qa3537954.html 質問 QNo.3537954 Unix初心者による初心者シェルプログラミングです。 で、shell環境を Bash に変更しました。 すると・・・・ 今のPCのKeyboardsのまま ls -ltr | grep 5月 とタイプ出切る事が、判明しました。 すいません。無知で・・・鈍感で・・・・ 訳の分からない落ちで・・・ どうして、bash だと?疑問は自己で解決するべく努力します。 k0y 氏のこのコマンドOK!です! ls -ltr|perl -lane 'print $_ if $F[5]=~/^1[^0-9]/' このコマンドについてはしっかりと使用して理解して今後の対Unixに役に立てるよう受け入れます。 今後も何か、回答にご協力頂けたらと思います。 色々、有難うございました。

その他の回答 (6)

  • k0y
  • ベストアンサー率100% (1/1)
回答No.6

grep使ってない上にperlを使って少しずるいですが ls -ltr|perl -lane 'print $_ if $F[5]=~/^5/' でだめですかね? 結構短いので、いけるかとおもっているのですが^^ 一応簡単な解説 ・perl のオプション e: perlをコマンドラインで実行 n: while(<>)、標準入力から一行ごとに読み取る a: split()、スペースを区切り文字として読み取った行を区切る -> 結果は @F という配列に入る l: chomp()、読み取った行に改行文字が含まれる場合取り除く ・perlでやってること スペースで区切られた文字群のうちもし(if)6番目($F[5]、0から数える)が 5から始まる(=~/^5/)場合その行($_)を表示する(print) ※ perlは配列全体(Array)を@で表し、$は変数や配列の一要素(Scalar)を表す 問題は1月を対象とするときに11月と12月が含まれてしまうってことですが....

Piranha
質問者

補足

回答有難うございます。 遅くなりましてすいません。 > grep使ってない上にperlを使って少しずるいですが いえいえ、ずるいもなにもありません。 なにせ、grep で充分いけるだろう!ぐらいの些細な知識しか持ち合わせておりませんで・・・ しかしperlが出てきますか、何だか思ったより一筋縄ではいかない(?)印象が出てきました・・・ > ls -ltr|perl -lane 'print $_ if $F[5]=~/^5/' > でだめですかね? > 結構短いので、いけるかとおもっているのですが^^ 行けます! > 一応簡単な解説 解説まで有難うございます。 理解力が低いのに勉強不足で・・・感謝してます! > 問題は1月を対象とするときに11月と12月が含まれてしまうってことですが.... ・・・・ですね。 むむむ、ココから先を求めると、コマンドが長くなりますやねぇ・・・

  • foobar
  • ベストアンサー率44% (1423/3185)
回答No.5

#3補足 linux(bash,GNU grep)で試したところ、 grep '^[rwxs-]\+ \+\w\+ \+\w\+ \+\w\+ \+\w\+ \+5' と+を\でエスケープする必要があるようでした。 (エスケープは不要な気もするのですが、なにか勘違いしてるかな。) あと、 \+\w\+ の繰り返しを()でくくって{4}で回数指定する方法でもよいようです。(こちらも、()などをエスケープする必要があるようです。) また、「**日以上経過したファイル」なら、#4さん回答にあるようにfindを使うのがよいかと思います。(findもオプション指定で、サブディレクトリ以下の検索をしないようにできたかと思います) その他、lsで-t(だったかな)オプションを使って、日時でソートして、、というのも場合によっては有効かもしれません。(頻繁に抽出作業をするのでなければ、日時でソートして前後を手動で削るというのもありかなと)

Piranha
質問者

補足

grep '^[rwxs-]\+ \+\w\+ \+\w\+ \+\w\+ \+\w\+ \+5' これは、残念ながらNGでした。 質問では省いてますが、 "ls -ltr" は叩いてます。 すいません、削除はしませんので sort する必要性はないです。

noname#243622
noname#243622
回答No.4

#2です。 日本語環境といっても、SJIS,EUC,UTF-8などありますから、その辺がうまくいかない原因なのでしょうが.... 一時的に英語環境にしたければ、 LANG=C ls -l | grep " May " でもいいとは思います。 ただ、日付が英語で出るのがいやなんですよね。多分。 後は余談かもしれないですので、該当しなかったら参考までに。 本当にしたい処理は、作成されてから半年以上たったログファイルを消そうとしているのかなと勝手に想像しました。 ということで、 find ./ -mtime +180 | xargs ls -l というのはどうでしょう。-mtime 180は変更があってから180日(半年を勝手に180日としていますが)という意味になります。-mtime +180とすると半年以上たったものということになります。 ただし、findコマンドは指定したディレクトリ以下も全部探しに言ってしまうので注意してください。 有無を言わさず削除したいのであれば、 find ./ -mtime +180 | xargs ls -l で削除できます。xargs コマンドは出力された内容を後ろにつける役割があります。まずはxargsコマンドをつけずにfindを実行してみてください。

Piranha
質問者

お礼

http://oshiete1.goo.ne.jp/qa3537954.html 質問 QNo.3537954 Unix初心者による初心者シェルプログラミングです。 で、shell環境を Bash に変更しました。 すると・・・・ 今のPCのKeyboardsのまま ls -ltr | grep 5月 とタイプ出切る事が、判明しました。 すいません。無知で・・・鈍感で・・・・ 訳の分からない落ちで・・・ どうして、bash だと?疑問は自己で解決するべく努力します。 おかげさまで、env、awk について学べました。 今後も何か、回答にご協力頂けたらと思います。 色々、有難うございました。

Piranha
質問者

補足

ちなみに削除はしません。 find ./ -mtime +180 ではないんですね、対象月なんです。 ですから、個人的に今の時点では、 > setenv LANG C > ls -l | grep May これで問題は無いんですがね。

  • foobar
  • ベストアンサー率44% (1423/3185)
回答No.3

#1です。 例えば(手元に試せる環境が無いので試してません+もっとエレガントな記述方法があるかと思います)、 grep '^[rwxs-]+ +\w+ +\w+ +\w+ +\w+ +5' というようなのが使えるかもしれません。 行頭(^)のあとrwxs-の繰り返し、一文字以上の英数字と一つ以上の空白が4回(単語4個)、5、という文字列を検索、という意味合いになります(と思います)。 (特に単語4回の繰り返しの部分は、もっとスマートな記述方法があるかと思いますが、、 grep '^[rwxs-]+( +\<.*\>){4} +5' でいいのかな、、 ) 正規表現に関しては、 http://tonetsutomu.com/tone/linux/Reference/RegularExp.htm などを参照いただければと。

参考URL:
http://tonetsutomu.com/tone/linux/Reference/RegularExp.htm
Piranha
質問者

お礼

http://oshiete1.goo.ne.jp/qa3537954.html 質問 QNo.3537954 Unix初心者による初心者シェルプログラミングです。 で、shell環境を Bash に変更しました。 すると・・・・ 今のPCのKeyboardsのまま ls -ltr | grep 5月 とタイプ出切る事が、判明しました。 すいません。無知で・・・鈍感で・・・・ 訳の分からない落ちで・・・ どうして、bash だと?疑問は自己で解決するべく努力します。 おかげさまで、正規表現について学べました。 今後も何か、回答にご協力頂けたらと思います。 色々、有難うございました。

noname#243622
noname#243622
回答No.2

日本語環境ではなくて、英語環境にしてはどうでしょう。 環境変数LANGをCに設定してください。 (cshの場合) setenv LANG C (bashの場合) export LANG=C そうすると "5月" の部分が "May" になりますから、 ls -l | grep " May " で取得するか ls -l | awk '$6=="May" {print}' で取得できるでしょう。 前者は月表示の前後にスペースがあることを期待してる表現です。後者は6列目が"May"だったらという意味になります。

Piranha
質問者

お礼

awk を学習した結果、 ls -ltr | awk '{print $6, $9;}' | grep '^5' 5月 abc-11.txt 5月 abc-6.txt 5月 abc-71.txt と、該当月と該当ファイル名だけを標準出力されるまでにしか 今のところならないのかな、と思われます。 これ以上だとスクリプトを作りこみ、コマンドとして用意しなくては ならないのかなぁ? とコマンドとして使用するのを敬遠してます・・・

Piranha
質問者

補足

これは、これも確かにありです。 早急的にはとてもイイと思いましたが、恒久的に考えると・・・ 社内環境上・・・・デメリットが浮上します。 awk については無知ですので、ちょこっとググって見てみましたが、 Mayでは無いほうで、いけるのかなと色々試して期待してみるのも、実際は全然いけてなく、結果NGなのが実情です。

  • foobar
  • ベストアンサー率44% (1423/3185)
回答No.1

grepの検索文字列を正規表現することで実現できるような気がします。 (空白で区切られた任意の単語5つ+"5"、というような感じで)

Piranha
質問者

補足

質問、補足の仕方に不備がありましたら、大変失礼なのですが、 上記の内容ですと以下のようになると理解し実際にこれで望んでいる結果は出力されました。 質問の例は、簡単にした為に実環境では 注:)△ は半角スペースを表しています。 ls△-l△|△grep△'..........△△△.△....△△△△△....△△△△△△△△△...△△5' とls -lの出力と同じ数の半角スペースを合わせる必要があるのには経験不足の為時間を費やしました。 結果は出たのですが、もしかしたらfoobar氏の言わんとしている回答例とは違うような気がするのですが、 もしよろしかったらこの方法でよかったのか、またアドバイスを頂けたらと思います。 尚、 △ は半角スペースを表しています。 と半角スペースの数を合わせる必要があるのには経験不足の為時間を費やしました。 結果は出たのですが、もしかしたらfoobar氏の言わんとしている回答例とは違うような気がするのですが、 もしよろしかったらこの方法でよかったのか、またアドバイスを頂けたらと思います。

関連するQ&A