web-dev-qa-db-ja.com

find -exec lsの出力をソートします

find … -exec ls -ls ;の出力をファイル名でアルファベット順に並べ替えることはできますか?

これは私のcronコマンドです:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

このコマンドは、大部分は問題なく動作します。ただし、結果は意味のある順序で並べ替えられていません。ファイル名フィールドで並べ替えると非常に便利です。

14
MaJ

ファイル名に改行が含まれていないと思います。

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

+の代わりに;を使用して-execアクションを終了すると、lsの呼び出しがバッチ処理されるため、処理が速くなります。 sortコマンドを使用してパイプでソートできます。 10番目のフィールドからソートを開始するように指示します(最初の9つはメタデータです:ブロック、権限、リンク数、ユーザー、グループ、サイズ、および3つの日付/時刻フィールド)。オプション-nは、ユーザーやグループに数値を使用するようにlsに指示します。これにより、空白を含むユーザーまたはグループの名前のリスクを回避できます。

または、zshを使用して、ファイル名を想定せずに glob qualifiers を使用してファイルを収集およびソートし、 zargs を使用して、コマンドラインでlsを複数回実行できます。長すぎるでしょう。 lsによる再ソートを回避するには、GNU ls(具体的には-fオプション)が必要です(別のアプローチは、zshの lszstatをエミュレートすることです) 。

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

POSIXは、ls-longリストの日付についてこれを言っています。

<date and time>フィールドには、ファイルが最後に変更されたときの適切な日付とタイムスタンプが含まれます。 POSIXロケールでは、フィールドは次の日付コマンドの出力に相当します。

date "+%b %e %H:%M"

...ファイルが過去6か月間に変更されている場合、または:

date "+%b %e %Y"

これを考慮し、ファイル名に改行がある場合、POSIXで指定されたls -qオプションを使用して改行が適切にグロブされることを確認すると、lsなしでfind結果なしの正規表現を準備することは比較的簡単です。

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

その場合、grepを使用すると、今日または昨日の日付を表す文字列を含む行のみが返されます。次のコマンドはそれに少し追加します。

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

lsオプションは次のもので構成されます。

  1. -aは、.dotで始まるファイルを含む、ディレクトリ内のすべてのファイルを返します。
  2. -l長いリスト
  3. -Rはすべての子ディレクトリを再帰的にリストします
  4. -cアクセス時間ではなく変更時間を表示する
  5. -qは、ファイル名に表示できない文字や?ab文字ではなく、シェルグロブ\tを返します

これらの結果は|pipeファイルを介してsedに渡されます。

  1. パス名の前の空白行と次の行
  2. dも含む-で始まる行(つまり、ディレクトリのdateではない)の行。
  3. パス名の行は出力されませんが、それらが指定するディレクトリに、フィルタリングしたファイルが実際に含まれている場合を除きます。

出力は次のようになります。

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

はい、それはLS_COLORSでも機能します。これはおそらくcronの優先度が低い可能性がありますが、オプションは開いています。

いずれにせよ、これは他のいくつかの可能な解決策に比べていくつかの重要な利点を提供します。

  1. そもそもfind + lsは複数の呼び出しを含みます-これは単一のlsプロセスのみを含み、これがすべてを確実にソートできる理由です-デフォルトで行うように-そしてsortも付随的に作られます。

  2. findsortlsを含むすべての解決策は、作業のほぼallを2回実行しています。 lsfindは両方とも、すべてのパス名とstatをすべてのファイルで解決します。 lssortは両方ともすべての結果をソートします。代わりに、単一のlsを使用するのがおそらく最善です。

  3. そしてもちろん、この回答のdatesedの部分があります。これについて注意する必要があるのは、難しい部分を実行し、最初に正規表現を取得する-1回だけです-その後、結果の取得、結果の取得、並べ替えの結果、および結果の並べ替えではなく、結果の単一のリストを整理するだけです。

  4. 他の解決策がそうする可能性があるように、これは改行を含むファイル名を壊しません。このソリューションには独自の注意点があります(次に説明します)が、それらは細かく、簡単に処理できます。私の意見では、これはここで最も堅牢なソリューションです。

上記のコマンドで問題が発生する可能性のあるケースは2つあります。最初のものはファイル名に?グロブを含みます-それはすでにここで提供される他のどのソリューションよりもより堅牢なソリューションであり、?が発生する可能性はそれ自体で十分に小さいため、解決する可能性がありますこれらのグロブは、複数のファイル名に一致する可能性があります。この問題の詳細については、 this を参照してください。

他の可能性には、誤検出が含まれます。たとえば、dateで検索しているgrep文字列と実際に一致するファイル名があるが、実際にはそれらのどちらの日にも変更されていなかった場合です。私はそれが問題であることを期待していませんが、問題がある場合はそれについて尋ねてください。おそらくこれを処理するために正規表現をより具体的にするのに役立つでしょう。

1
mikeserv

Findの結果を並べ替えてパイプし、各行に対してlsを実行しませんか?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
1
groxxda

実際には、find、xargs、lsを組み合わせて使用​​できます。

次にコマンドの例を示します。find . -type f -print0 | xargs -0 ls -lt

  • findは、現在のディレクトリにあるすべてのファイルを再帰的に検索します。
  • xargsは、このファイルのリストを1回の呼び出しでlsコマンドに渡します(findARG_MAXファイルより少ない場合)。
  • ls -ltは、これらのファイルを時間順にソートし、出力をフォーマットします

システムARG_MAXを取得するには、次のように入力します。

$ getconf ARG_MAX
> 2621440
0
Max