SunOS の csh で特定の時間以降に作成されたファイルを検索する

SunOS の csh で特定の時間以降に作成されたファイルを検索する

SunOS システムで、、、およびを使用して、午後 7 時以降に作成されたすべてのファイルを検索しようとしてcshいますlsawk

ls -l  "${Source_files_Dir}"/*.zip| awk -v today="$(date "+%b %d")" '{
date=$6" "$7; time=$8; if (date == today && substr(time,1,2) >= 19)
print $9 }'|xargs -n 1 basename

このコマンドは では機能しますkshが、 では機能しませんcsh。 でこれを実現するにはどうすればよいでしょうかcsh?

注:-newermtオプションはfindSunOS ではサポートされていないため、上記のコマンドを使用しようとしましたls

答え1

いずれにしても、このアプローチはかなり不安定なので、以下を使用する方が良いでしょうperl:

perl -MPOSIX -MFile::Basename -le '@start = localtime; @start[0..2] = (0,0,19); $start = mktime(@start); for (@ARGV) {print basename$_ if @s = stat$_ and $s[9] >= $start}' -- "$Source_files_Dir"/*.zip

今世紀に csh を使用する理由がわかりませんが、改行文字が含まれているcsh場合、上記は正しく機能しないことに注意してください。を に置き換えると、csh ではより適切になります (ただし、他のシェルでは機能しなくなりました)。$Source_files_Dir"$Source_files"$Source_files:q

Solaris (旧称 SunOS) も通常はzshインストールされており、次の操作を実行するだけです。

autoload age
print -rC1 -- $Source_files_Dir/*.zip(Ne[age 19:00]:t)

あなたのアプローチの問題点をいくつか挙げてみましょう:

  • ls -l "${Source_files_Dir}"/*.zip:$Source_files_Dirが で始まる場合-、 ではオプションとして扱われますls。一般に、--後続が変数である場合はオプションの終わりをマークする必要があります。
  • いずれかの zip ファイルがディレクトリ タイプの場合、その内容が一覧表示されます。globlsまたは一般的な変数データで使用する場合は、通常、次のオプションを使用します-dls -ld -- ...
  • 特に csh では、 に$Source_files_Dir改行文字が含まれていると構文エラーが発生します。 は、$Source_files_Dir:q上記のように csh ではより適切です。
  • いずれにしても、行ベースls -lの出力を処理しているため、ファイル パス (ファイル名と、レポートされるシンボリック リンク ターゲット) に改行文字が含まれていないと想定していますls
  • 日付/時刻がフィールド 6、7、8 にあると想定していますが、ユーザー名またはグループ名に空白が含まれていると、フィールドが崩れてしまいます。-nの代わりに (またはに加えて)を使用して-l数値の uid/gid を取得すると、より堅牢になります (また、潜在的にコストのかかる名前への変換を回避できます)。
  • date +%dは 0 が埋め込まれた数値を出力しますが、多くのls実装と多くのロケールでは (これは C/POSIX ロケールの POSIX 要件です)、ls -lスペースが埋め込まれた数値 ( date +%e) を出力します。
  • ls -lMon dd HH:MM将来の日付ではなく最近の日付を出力しますが、Mon dd YYYYあなたのアプローチでは処理できない他の日付を出力します。
  • オプションがない場合-L、シンボリックリンクの場合は、シンボリックリンクが指す zip ファイルの変更時刻ではなく、シンボリックリンクの変更時刻が一覧表示されます。perlまたは は、stat()ターゲットの mtime で機能しますzshage
  • あなたの場合{print $9}、ユーザー名/グループ名に空白が含まれていないことに加えて、ファイル パスにも空白が含まれていないことを前提としています。
  • xargsファイル パスにバックスラッシュまたは引用符が含まれている場合、また、C ロケールで実行していない場合、ロケールのエンコーディングでテキスト エンコードされていないファイル名では、その生の出力での使用は失敗します。
  • ディレクトリ内に非表示になっていない zip ファイルがない場合、csh ではNo matchエラーが発生してls実行されません (少なくとも、lsパターンを文字通りに呼び出す Bourne スタイルの動作よりはましです)。ただし、xargs実行はされます。また、basename引数なしで 1 回実行されるため、混乱を招くエラーが発生する可能性があります。

答え2

csh の回答が得られました。今日の日付を ではなく、変数に格納する代わりに'$'を使用しました。backtickstodayawk

set today=`date "+%b %d"`
ls -l "$Source_files_Dir"/*.zip | awk -v today="$today" ' \
{ \
    date=$6" "$7; \
    time=$8; \
    if (date == today && substr(time,1,2) >= 19) print $9; \
}'|xargs -n 1 basename

関連情報