検索結果の -exec コマンドで配列に値を割り当てることはできません。

検索結果の -exec コマンドで配列に値を割り当てることはできません。

7日以上経過したファイルを削除するために、検索結果を配列として配布するために次のコマンドを作成しました。

F_ARR[0]=''
unset F_ARR
find "$CDIR" ! -type d -mtime +7 -exec sh -c '
    for pathname; do
        F_ARR+=("$pathname")
    done' sh {} +
echo ${#F_ARR[@]}

ただし、F_ARR配列の長さを印刷すると0が表示されます。私のコードに間違いがありましたか?

ベストアンサー1

find ... -exec sh -c 'sh code' {} +

bash / kshシェルでfind1つ以上のコマンド呼び出しを実行する新しいプロセスでコマンドを実行します。このコードを解釈する呼び出しの変数にのみ影響を与えるshことができます(ただし、配列サポートを意味するわけではありません)。sh codeshsh

見つかったファイルのパスを現在のシェルの配列に保存するには、そのfindシェルで割り当てを実行する必要があります。

4.4+ では、bash次のことができます。

readarray -td '' F_ARR < <(find "$CDIR" ! -type d -mtime +7 -print0)

findサポートしていない場合-print0に置き換えることができます-exec printf '%s\0' {} +

(以前のバージョンについては、bash以下を参照してください。同様の質問に答えてこれを行うには?)。

zshここでは、代わりにシェルを使用することもできます。

f_arr=($CDIR/**/*(NDm+7^/))

上記との違いは次のとおりです。

  • ファイルのリストがソートされました。oNglob修飾子を追加してソートを無効にできます。
  • $CDIR8日を超えてもそれ自体は含まれません。
  • $CDIRディレクトリへのシンボリックリンクの場合zshでも、そのディレクトリに移動します。

質問にタグを付けたので、bashkshのさまざまな実装とバリアント、またはksh(ksh88、ksh93、David Kornの将来のksh2020(元)、pdksh、およびその派生(OpenBSDなど)shmksh

ほとんどの機能はおよびbashで提供され、一部の機能はおよびで提供されます。これは基本的な機能であり、他の場所では見つからないいくつかの機能の1つです。ksh88ksh93zshmkshreadarraybash

-dksh93は後でbash(2000)、zsh(2003)、およびmksh(2011)によってコピーされたオプションを1993年にread追加しましたが、bash、zsh、mksh、およびksh2020はnull区切り文字と一緒にNULで区切られたレコードを使用します。処理できます。プロセス置換はksh86(1986)に追加されましたが、pdkshベースのkshバリアントのいずれもサポートしていないため、上記の以前のバージョンで説明した方法はすべてのbashkshバージョンでは機能しません(zshのkshエミュレーションモードを除く)。

ksh88、ksh93、およびpdkshベースのシェルの1つのオプションは、出力を後処理してfind配列を定義し、次を使用してコードを評価できるシェルコードを生成することですeval

eval set -A F_ARR "$(
  LC_ALL=C find "$CDIR" ! -type d -exec awk -v q="'" -- '
    BEGIN {
      for (i = 1; i < ARGC; i++) {
        gsub(q, q "\\" q q, ARGV[i])
        printf " %s", q ARGV[i] q
      }
      exit
    }' {} +
)"

(これは$CDIRまたはで始まらないと仮定します。可能であれば、いくつかの実装ではを使用できます。とにかくで始まるとブロックされます)。+-kshset -A F_ARR ---find

set -A F_ARRすべてのPOSIX shに同じアプローチを使用でき、次の代わりにset --POSIXシェル用の配列を埋めることができます"$@"

おすすめ記事