
SunOS システムで、、、およびを使用して、午後 7 時以降に作成されたすべてのファイルを検索しようとしてcsh
いますls
。awk
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
オプションはfind
SunOS ではサポートされていないため、上記のコマンドを使用しようとしました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 ファイルがディレクトリ タイプの場合、その内容が一覧表示されます。glob
ls
または一般的な変数データで使用する場合は、通常、次のオプションを使用します-d
。ls -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 -l
Mon dd HH:MM
将来の日付ではなく最近の日付を出力しますが、Mon dd YYYY
あなたのアプローチでは処理できない他の日付を出力します。- オプションがない場合
-L
、シンボリックリンクの場合は、シンボリックリンクが指す zip ファイルの変更時刻ではなく、シンボリックリンクの変更時刻が一覧表示されます。perl
または は、stat()
ターゲットの mtime で機能しますzsh
。age
- あなたの場合
{print $9}
、ユーザー名/グループ名に空白が含まれていないことに加えて、ファイル パスにも空白が含まれていないことを前提としています。 xargs
ファイル パスにバックスラッシュまたは引用符が含まれている場合、また、C ロケールで実行していない場合、ロケールのエンコーディングでテキスト エンコードされていないファイル名では、その生の出力での使用は失敗します。- ディレクトリ内に非表示になっていない zip ファイルがない場合、csh では
No match
エラーが発生してls
実行されません (少なくとも、ls
パターンを文字通りに呼び出す Bourne スタイルの動作よりはましです)。ただし、xargs
実行はされます。また、basename
引数なしで 1 回実行されるため、混乱を招くエラーが発生する可能性があります。
答え2
csh の回答が得られました。今日の日付を ではなく、変数に格納する代わりに'$'
を使用しました。backticks
today
awk
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