現在のディレクトリの最後に変更されたサブディレクトリに切り替える

現在のディレクトリの最後に変更されたサブディレクトリに切り替える

定期的に複数のディレクトリに複数のファイルを生成するアプリケーションがあるため、作成された最新のファイル、つまり最新のディレクトリ(作成または更新)に生成されたファイルを確認する必要があります。ファイル名はすべてのディレクトリで同じままであるため、ディレクトリを最後に変更されたサブディレクトリに変更する単純なスクリプトのみが必要です。

[更新]ほとんどの回答を見て、ディレクトリ名が動的であるため(一部のユーザー入力やタイムスタンプによって)dir [1、2、3]などのディレクトリパターンを想定できないことを明確にする必要があると思いました。または同様

答え1

これには複雑な配管は必要ありません。さらに、何もする必要はありませんfind。すべてのファイルがどこにあるかは既に知っていますが、そのうちどのファイルが最新であるかはわかりません。これは扱いやすいです。

これを実証するために、ここに小さなテストがあります。

mkdir ./dir1 ./dir2 ./dir3

for d in 1 2 3
do  touch ./dir$d/samefile
    sleep 1
done

これによりテストセットが作成されます。さて、どちらが最新ですか?

set -- ./dir[123]/samefile
while [ -e "$2" ]
do  [ "$1" -nt "$2" ] && 
    set -- "$@" "$1"
shift; done
printf %s\\n "$@"

それは私に教えてくれます。

出力

./dir3/samefile

touch作業順序を自由に変更できます。これにより、正しい情報が提供されます。必要なのは、次の関数内の小さなシェルループだけです。

newd() { ${2:+:} return 1
    while [ -e "$2" ] && [ -e "$1" ]
    do  [ "$1" -nt "$2" ] && 
        set -- "$@" "$1"
    shift; done
    ${2+false} cd "${1%/*}"
}

これはデモとは少し異なるため、引数が2つ未満の場合、または引数が実際のパス名でない場合は、確実に失敗します。

これで、次のように呼び出すことができます。

newd ./path/to/file1 ./path/to/file2

...など - 好きなだけ多くの引数を持つことができます。

または私のテストケースでは、次のようになります。

newd ./dir[123]/samefile ; pwd

出力

/home/mikeserv/test/dir3

答え2

実行する操作とファイル構造によっては、次のような他の可能性があります。

ls -1tq /dir/*/readme.txt | head -n 1

/dir/のサブディレクトリにある最新のreadme.txtのフルネームを返します(非再帰的)。

ファイル名の一部ではなくパスの一部として*を使用することは一般的に知られておらず、言及する価値があると思いました。

file=$( ls -1tq /dir/*/readme.txt | head -n 1 )
cd $( dirname "$file" )

答え3

より移植性のために、以下を使用できますperl

$ perl -MList::Util=reduce -le '
    BEGIN { $dir = "." }
    opendir DIR,$dir;
    print shift @{(reduce {$a->[1] > $b->[1] ? $a : $b}
                   map {[$_,(stat($_))[9]]}
                   grep { -d and !/^..?$/ }
                   readdir DIR)}
'
.Skype

$dir検索したいディレクトリに変更します。

どのように動作しますか?

  • readdirdirハンドル内のすべてのファイルとディレクトリのリストを返します。opendir
  • grep { -d and !/^..?$/ }.:すべてのディレクトリ、スキップ、およびディレクトリをインポートします..
  • map {[$_,(stat($_))[9]]}:要素が配列参照であり、2つの要素を持つ配列を作成します。
    • 最初はディレクトリ名です。
    • 2番目は修正時間です。
  • reduce {$a->[1] > $b->[1] ? $a : $b:max 関数と同様に、配列の各要素を修正時間である 2 番目の要素と比較します。
  • @{...}配列を逆参照し、shift最初の要素であるディレクトリ名を取得します。

答え4

man find短い答え:「時間」オプションを見てください。その後、ファイルを見つけて、-printfオプションを使用して利用可能なファイルパスを表示します。cd <path>


find現在のディレクトリとそのサブディレクトリから最後にアクセスしたファイル(過去24時間以内)のDIRを使用して抽出する方法

lastAccDir="$(find 2>/dev/null .-type f -atime 1 -printf "%a~%h\n" | sort -r | head -n 1 | cut -d~ -f2)"

または行連続と同じ(読みやすさが高い)

最後のディレクトリ = "$(
2> / dev / nullを見つけます。 -type f \ -atime 1 -printf "%a~%h\n" \
 |ソート-r\
 |ヘッド-n 1\
 |cut-d~-f2
)」

(過去24時間)これ-atime 1により結果が空になる可能性があります。

test ! -z "$lastAccDir" && cd "$lastAccDir"
その後、空でない結果を確認し、空でない場合はディレクトリに移動します。

関連情報