2つのスクリプトを作成しました。まず、すべてのフォルダのmtimeタイムスタンプを読み取り、time_old.txtに1行ずつ書き込みます。
for d in */ ; do
time_old=$(stat --format %Y "$d")
escaped=$(printf %q "$d")
echo "$time_old $escaped" >> time_old.txt
done
2番目は行を再読み込みし、touch
フォルダの古いタイムスタンプを使用して実行されます。
input="time_old.txt"
while IFS= read -r line
do
echo "$line"
touch_output=$(touch -m -d @$line)
echo "$touch_output"
done < "$input"
これは、同様のフォルダには機能しますFolder1
が、名前が 。Folder2
インフォルダには機能しません。Foo & Bar
私の間違いはどこにありますか?
ベストアンサー1
代わりに、次のことを行います(GNUツールの前提)。
find . ! -name . -prune -type d -printf '@%T@\0%p\0' > time_old.list
復元:
xargs -t -a time_old.list -r0 -n2 touch -md
を使用する場合は、printf %q
結果をシェルコードとして解釈する必要があります。それは次のとおりです。
find . ! -name . -prune -type d -printf 'touch -md @%T@ ' \
-exec printf '%q\n' {} \; > time_old.bash
そして:
bash -v ./time_old.bash
また覆います。
printf
ただし、この非標準をサポートし、%q
シェル言語と互換性のある形式でファイルパスを引用するスタンドアロンユーティリティが必要です。これが保証されていないと危険になる可能性があります。これにより、ディレクトリごとに1つのプロセスを分岐して実行すると効率が低下します(stat
GNUアプローチと同様)。回避できる場合は、シェルが外部入力から生成されたコードを解釈することはできません。
また、touch
標準出力には何も書きませんのでoutput=$(touch...)
意味がありません。
zsh
ここでは、安全な引用演算子(単一引用符を使用すると、ファイル名に含まれる文字や文字以外のファイル名に関係なく安全でなければならず、shに似たシェル(yashを除く)と互換性がなければなりません)をstat
使用することもできます。実際にはGNUよりも前ののstat
で、GNUismに頼る必要はありません。
zmodload zsh/stat
{
for d (*(ND/))
stat -A t -F @%s.%9. +mtime -- "$d" &&
print -r touch -d $t -- ${(qq)d}
} > time_old.sh
そして回復を使用してくださいsh -v ./time_old.sh
。