タッチコマンドのフォルダ名をエスケープする方法は?

タッチコマンドのフォルダ名をエスケープする方法は?

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つのプロセスを分岐して実行すると効率が低下します(statGNUアプローチと同様)。回避できる場合は、シェルが外部入力から生成されたコードを解釈することはできません。

また、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

おすすめ記事