Solarisでは、次のように元の拡張子を保持しながら、名前の現在のタイムスタンプを含むフォルダ内のすべてのファイル名を変更したいと思います。
test1.txt > test1.date.txt
これを試しましたが、名前の最初の部分を失いました。
find * -prune -type f -name '*.txt' -exec mv {} {}.$(date +'%Y%m%d%H%M').txt \;
私が逃したものは何ですか?
答え1
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ではテストされていませんが、標準のコンポーネントやオプションなどを使用します。
呼び出す前にタイムスタンプを一度だけ計算するには、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つのコマンドの行連続性に注意してください)
ファイルがある場合一つディレクトリでループを実行するだけです。
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つの文字を置き換えるか、変更されていない文字列を使用するかは実装によって定義されます。。
答え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" {} ';'
恥ずかしいことにunix.stackexchangesh
@Kulasanandaがリンクを提供しましたが、呼び出しが設定された変数になる方法が好きですsh -c mv
。
甘い。