次のように、Solarisで、元の拡張子を保持したまま、名前に現在のタイムスタンプを含めて、フォルダ内のすべてのファイルの名前を変更したいと思います。
test1.txt> test1.date.txt
私はこれを試しましたが、名前の最初の部分を失います:
find * -Prune -type f -name '*.txt' -exec mv {} {}.$(date +'%Y%m%d%H%M').txt \;
何が欠けていますか?
_find . -type f -name '*.txt' -exec sh -c '
now=$( date +%Y%m%d%H%M )
for pathname do
mv "$pathname" "${pathname%.txt}.$now.txt"
done' sh {} +
_
これにより、現在のディレクトリ内またはその下にある通常のファイルのすべてのパス名が検索され、その名前は_.txt
_で終わります。これらのバッチの場合、短いシェルスクリプトが呼び出されます。このスクリプトは、最初にタイムスタンプを取得し(効率を上げるために、バッチごとに1回しかありません)、指定されたパス名をループします。
パス名ごとに、最後の_.txt
_を削除し(_${pathname%.txt}
_を使用)、ドット、タイムスタンプ、および_.txt
_を追加することにより、パス名を変更します。
これはSolarisではテストされていませんが、標準のコンポーネントとオプションのみを使用しています。
タイムスタンプを1回だけ計算するには、find
を呼び出す前に、
_now=$( date +%Y%m%d%H%M ) \
find ...as before (but without assigning to now)...
_
または
_env now="$( date +%Y%m%d%H%M )" \
find ...as before (but without assigning to now)...
_
(上記の2つのコマンドの行の継続に注意してください)
ファイルがsingleディレクトリにある場合は、ループを実行するだけです。
_now=$( date +%Y%m%d%H%M )
for pathname in ./*.txt; do
mv "$pathname" "${pathname%.txt}.$now.txt"
done
_
これは、パターン_./*.txt
_が、名前を変更するすべての名前に一致すると想定しています。
関連:
あなたの{}.$(date +'%Y%m%d%H%M').txt
は移植性がありません。 find
の一部の実装で機能する可能性がありますが、_{}
_が別の文字列と一緒に出現する場合、_{}
_を現在のパス名に展開する実装は必要ありません。
POSIX標準は からの関連テキスト:
_
utility_name
_または2文字のみを含む引数_{}
_は、現在のパス名に置き換えられます。 _utility_name
_または引数文字列に2つの文字_{}
_が含まれているが、2つの文字_{}
_だけではない場合、findがそれらを置き換えるかどうかは実装定義です2文字または変更なしの文字列を使用します。
別の方法ですが、solaris
との互換性がよくわかりません...
from=txt
to=$(date +%Y%m%d%H%M).txt
find * -Prune -type f -name "*.$from" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$from" "$to" {} ';'
@Kulasanandaによって与えられた nix.stackexhange リンクから恥知らずに盗まれましたが、sh
からの呼び出しがsh -c mv
の変数を構成する方法が好きです。
甘い。