回答:
現在のディレクトリ内のすべての(グロビング)ファイルの名前を変更するにはクイックと汚いバッシュワンライナーfilename.txt
にfilename.txt-20120620
:
for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done
進取の気性のあるBashオタクは、それを打破するためのエッジケースを見つけるでしょう。:)
明らかに、これはファイルの最後に日付のようなものが既にあるかどうかをチェックするなどの望ましいことを行いません。
date
実装ですか?私のGNU date
は入力を処理していないようです。
以下は、goldschrafeのワンライナーのバージョンです。
ダッシュで始まるファイル名にも対応しています
for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done
date -r "$f" +%Y%m%d
かどうかは動作しませんPOSIXLY_CORRECT
環境にあります。一般的に、オプションは他の引数の前に配置する必要があります。
"${f}"
。
必須のzshワンライナー(オプションのコンポーネントの1回限りのロードはカウントしません):
zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'
私たちは、使用stat
から組み込みzsh/stat
モジュール、およびzmv
ファイルの名前を変更する機能を。そして、もしあれば、拡張子の前に日付を置く追加があります。
zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'
私が理解したように、私たちは修正日が何であるかを事前に知りません。そのため、各ファイルから取得し、出力をフォーマットし、ファイル名に変更日が含まれるように各ファイルの名前を変更する必要があります。
このスクリプトを「modif_date.sh」のような名前で保存し、実行可能にすることができます。ターゲットディレクトリを引数として呼び出します。
modif_date.sh txt_collection
「txt_collection」は、名前を変更するすべてのファイルがあるディレクトリの名前です。
#!/bin/sh
# Override any locale setting to get known month names
export LC_ALL=c
# First we check for the argument
if [ -z "$1" ]; then
echo "Usage: $0 directory"
exit 1
fi
# Here we check if the argument is an absolute or relative path. It works both ways
case "${1}" in
/*) work_dir=${1};;
*) work_dir=${PWD}/${1};;
esac
# We need a for loop to treat file by file inside our target directory
for i in *; do
# If the modification date is in the same year, "ls -l" shows us the timestamp.
# So in this case we use our current year.
test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'`
case ${test_year} in *:*)
modif_year=`date '+%Y'`
;;
*)
modif_year=${test_year}
;;
esac
# The month output from "ls -l" is in short names. We convert it to numbers.
name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'`
case ${name_month} in
Jan) num_month=01 ;;
Feb) num_month=02 ;;
Mar) num_month=03 ;;
Apr) num_month=04 ;;
May) num_month=05 ;;
Jun) num_month=06 ;;
Jul) num_month=07 ;;
Aug) num_month=08 ;;
Sep) num_month=09 ;;
Oct) num_month=10 ;;
Nov) num_month=11 ;;
Dec) num_month=12 ;;
*) echo "ERROR!"; exit 1 ;;
esac
# Here is the date we will use for each file
modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year}
# And finally, here we actually rename each file to include
# the last modification date as part of the filename.
mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}"
done
stat
ユーティリティがあるか、まったくありません。
ls
信頼できないことに注意してください。一部のUNIXバリアントでは、ユーザー名とグループ名にスペースを含めることができます。これにより、日付列の位置合わせが無効になります。
ls
として表示される日付/時刻は、現在の年でなければならないことを前提としています。本当じゃない。過去6か月間です。それは前年にある可能性があります(たとえば、2016年9月27日から2016年12月31日までは過去6か月以内です)。(6)GregのWiki(すでに@Gillesが引用している)をオウムする危険があるため、改行とスペースを含むファイル名はこれを失敗させる可能性があります。…(続き)
casのone-linerのバージョン(goldschrafeのonelinerに基づく)は、べき等性で拡張されています。
すなわち、日付時刻でファイルに接頭語をつけて、日付時刻接頭語をまだ持っていないものだけのためにこれをするために拡張されました。
ユースケース:ディレクトリに新しいファイルを追加し、まだ存在していないファイルに日時のプレフィックスを追加する場合に役立ちます。
for f in * ; do
if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
fi;
done
for f in *.jpg ; do jhead -ft "$f" ; done
ソース:unix.stackexchange.com/a/290755/9689