これまで私はこれを持っています:
sudo find /path/to/dir -type f |
xargs -d "\n" sudo stat -c "%Y %n" |
{arithmetic to check if %Y is between 1685518962 and 1685624474??} |
{show file path}
参考までに、私は知っていますが、find -newermt
コマンドラインで算術を実行することについてより一般的に質問されます。
明確にするために、私は行を望んだ。
TCSHやBASHも大丈夫ですが、他のシェルを教えてくれてありがとう。
答え1
ファイルのリストを処理するには、NULで区切られたレコード(-print0
for find
、-0
for xargs
)を使用します。改行はファイルパスの他の文字(または非文字)で有効なためです。
すでにGNU拡張機能を使用しているので、次のことができます。
sudo find /path/to/dir -type f '(' \
-newermt @1685518962 ! -newermt @1685624474 -exec something with {} + \
-o -exec something-else with {} + ')'
GNUコマンドが導入される前に、GNUはfind
(より良いインターフェースを介して)ファイルからメタデータを報告することができました。stat
後処理では、gawk/mawk、perl、zsh など、NUL で区切られたレコードおよび浮動小数点演算をサポートするツールを使用できます。
sudo find -H /path/to/dir -type f -printf '%T@\0%p\0' |
LC_ALL=C gawk -v RS='\0' -F: '
{mtime = $0; getline file}
mtime > 1685518962 && mtime <= 1685624474 {
# something with mtime and file
}'
そしてperl
:
sudo find -H /path/to/dir -type f -printf '%T@\0%p\0' | perl -0lne '
$mtime = $_; $file = <>;
if ($mtime > 1685518962 && $mtime <= 1685624474) {
# something with $mtime and $file
}'
ここに提供されている例を含むすべてのコードを1行に配置できます。ゴルフ練習なら、perl
次の中で最も適しています。
sudo find -H /path/to/dir -type f -printf '%p\0%T@\0'|perl -0lne'$m=<>;{...}if$m>1685518962&&$m<=1685624474'
または使用している場合は、zsh
これらのファイルを処理するためにシェルが必要な場合:
sudo find -H /path/to/dir -type f -printf '%T@/%p\0' |
while IFS=/ read -rd '' mtime file; do
(( mtime > 1685518962 && mtime <= 1685624474 )) &&
something with $mtime and $file
done
それでも、zsh
ほとんどの機能が組み込まれていますが、GNUismには依存しませんが、おそらく遅くなる組み込みfind
機能stat
(GNU以前のバージョン)もあります。stat
sudo zsh -c '
zmodload zsh/stat
for file ( /path/to/dir/**/*(ND.) ) {
stat -LF %s.%N -A mtime +mtime -- $file &&
(( mtime > 1685518962 && mtime <= 1685624474 )) &&
something with $file and $mtime
}'
今日、私はtcshを使用して安定して作業を行うことはほとんど不可能なので、使用しません。しかし、あなたが言及したので、tcshは再帰ワイルドカードをサポートしていることに注意してください(2010年bashの直後にzshからコピーされます)。 -ファイルのmtime検索をサポートしますが、1秒未満の精度はサポートせず(算術はとにかく整数のみ可能です)、シンボリックリンク確認後にのみ可能です。
set globstar globdot
foreach file ( /path/to/dir/** )
if ( -f $file:q && ! -l $file:q ) then
@ mtime = -M $file:q
if ( $mtime > 1685518962 && $mtime <= 1685624474 ) then
something with $file:q and $mtime
endif
endif
end
他の人は完全なナノ秒精度でmtimeを取得しますが、浮動小数点タイプと//double
結果を使用するほとんどのコンピュータ/ Cコンパイラは、今日のタイムスタンプに必要な精度を維持できません。awk
perl
zsh
たとえば、ほとんどは最後に変更されたファイルがどこにあるかを報告しません1685518962.000000001
。これはあなたにとって大きな問題ではないかもしれません。たとえば、特定のマイクロ秒以内に最後に変更されたファイルを高精度で見つける必要がある場合などです。
また、注:環境変数は実行するコマンドにsudo
渡され、その変数にはすべての引数が含まれているため失敗する可能性があります。SUDO_COMMAND
xargs sudo cmd
「人論が多すぎる」execve()
ファイル数が多い場合は、パラメータと環境文字列の累積サイズが制限されているためエラーが発生するため、実行できますが、xargs
その間に累積サイズが倍増して実行できない場合がありますsudo
。sudo
cmd
この理由とsudo
数回の呼び出しを実行するのに時間が節約されるため、ここでは1回だけ呼び出すこともできますsudo xargs cmd
。sudo
sudo sh -c '...'
¹これは、任意の精度算術が有効になっている場合は、任意の精度算術を使用するか、より一般的に秒とナノ秒を別々に比較するか(またはシェル/演算子が実行できます)、数値に数値を使用して-MvPREC=100
最新バージョンのオプションで解決します。できます。固定サイズのバイナリに変換する代わりに文字列比較を実行します(たとえば、数値ソートパラメータ拡張フラグを使用する代わりにwithを使用)。gawk
-Mbignum
perl
-newertmt
[
-nt
() [[ $1 = ${${(n)@}[1]} ]] $t1 $t2
(( t1 < t2 ))
zsh
n
答え2
これは仕事のように聞こえますawk
。
sudo find /path/to/dir -type f |
xargs -d "\n" sudo stat -c "%Y %n" |
awk '$1 > 1685518962 && $1 < 1685624474 {print}'
次のオプションをxargs
使用して削除できます。-execdir
find
sudo find /path/to/dir -type f -execdir stat -c "%Y %n" {} + |
awk '$1 > 1685518962 && $1 < 1685624474 {print}'
答え3
まあ、bashは許可されています。
#!/bin/bash
shopt -s dotglob globstar extglob nullglob
oldest=1685518962
newest=1685624474
for file in **/*; do
# check for regular file-ness
modtime=$(stat -c '%Y' -- "${file}")
[[ ( ! -L ${file} ) \
&& -f ${file} \
&& ( ${modtime} -gt ${oldest} ) \
&& ( ${modtime} -le ${newest} ) ]] \
&& {
# do stuff
}
done
Zshはglobbingが簡単にできることに少し可愛い
#!/usr/bin/zsh
zmodload zsh/stat
oldest=1685518962
newest=1685624474
for file in **/*(.ND); do
modtime=$(zstat -L +mtime -- "${file}")
[[ ${modtime} -gt ${oldest} \
&& ${modtime} -le ${newest} ]] \
&& {
# do stuff
}
done
はい問題のため文字通り算術を要求すると、zshとbashの両方が拡張で算術をサポートすることを指摘します。$(( ${modtime} - ${oldest} ))
下限秒以降の秒数を通知します。 Zshの算術関数は、特に浮動小数点では少し優れています。
答え4
他の回答の提案にもかかわらず一般的に言えば、パイプラインで使用できる 1 行シェル算術フィルタ関数を生成するには、2 つのコマンドを組み合わせる必要があります。
xargs
入力ラインをマッピングする機能、sh
シェル算術関数へのアクセス
パターンとしてxargs -L1 sh -c '_() { ... }; _ "$@"'
具体的な例を見ると、次のようになります。
find ...
| xargs stat ...
| xargs -L1 sh -c '_() { [ 1685518962 -le $0 -a $0 -le 1685624474 ] && echo $@; }; _ "$@"'
これはここにあるような迅速で汚れた作業に役立ちます。ただし、データボリュームがある場合など、Map-Reduce機能を備えたツールを展開したいと思いますawk
。