複数のファイルの名前を同じパターンの新しいファイルにまとめて変更する多くの例が見つかりました。しかし、あるファイルの名前を固定ファイル名に変更したいと思います。私は部分的に日付に基づく変数名を持っていますが、名前に他のランダムな文字を含む新しいファイルを頻繁に受け取ります。その後、いくつかのsed
タスクを実行してからデータベースにインポートできるようにファイル名を変更したいと思います。これにより、両方のファイルが削除されます。
受け取る | 考える |
---|---|
20210809-random-numbers.txt |
new_file.txt |
私は試した:
mv *.txt new_file.txt
単一のオプションに対する複数のオプションなので、これはうまくいかないと思います。
答え1
ファイルを探したいとしましょう。今日の日付YYYYMMDD
形式はファイル名の先頭にあり、パターンと一致し、YYYYMMDD-*.txt
名前をに変更しますnew_file.txt
。このbash
スクリプトは次のことを行います。
#!/bin/bash
# Make non-matching globbing patterns disappear.
shopt -s nullglob
# Get today's date.
printf -v today '%(%Y%m%d)T' -1
# Get names in the current directory matching our pattern.
set -- "$today"-*.txt
# Sanity check.
if [ "$#" -ne 1 ]; then
printf 'There are %d names matching "%s-*.txt", expected 1\n' \
"$#" "$today" >&2
exit 1
fi
# Inform user of action and proceed.
printf 'Renaming "%s" into "new_file.txt"\n' "$1"
mv -f "$1" new_file.txt
これは現在のディレクトリ外の名前と一致し、単一のファイルが予想される形式と一致すると名前が変更されますnew_file.txt
。ファイルが複数またはゼロであってもパターンと一致する場合は、ユーザーに通知して終了します。
一致するファイル名は、組み込みコマンドで設定された位置引数のリスト(たとえば、、$1
など$2
)に保存されます。このリストの長さはシェルの特殊変数によって保持され、単一のファイル名の一致が期待されます。$3
set
$#
テスト:
$ ls
script
$ ./script
There are 0 names matching "20210808-*.txt", expected 1
$ touch 20210808-blahblah-{1..5}.txt
$ ls
20210808-blahblah-1.txt 20210808-blahblah-4.txt
20210808-blahblah-2.txt 20210808-blahblah-5.txt
20210808-blahblah-3.txt script
$ ./script
There are 5 names matching "20210808-*.txt", expected 1
$ rm 20210808-blahblah-[2-5].txt
$ ls
20210808-blahblah-1.txt script
$ ./script
Renaming "20210808-blahblah-1.txt" into "new_file.txt"
$ ls
new_file.txt script
答え2
date
(man date
)(+format
および--date=
オプション)、find
(man find
)、および慎重なシェル引用符()を使用しman bash
て、次の操作を実行します(テストされていないが確認に使用されますshellcheck.org
)。
#!/bin/bash
# Yesterday's file
tgt="$(date "+%Y%m%d" --date="yesterday")"
# Today's file
tgt="$(date "+%Y%m%d" )"
# find the file - check to ensure we find only 1 file
file="$(find $PWD -maxdepth 1 -type f -name "${tgt}\*.txt" -print)"
if [[ $(echo "$file" | wc -l) -ne 1 ]] then
echo "Too many files $file"
exit 1
fi
echo mv "$file" new_file.txt
# or just process `"$file"` with `sed`.
exit 0
答え3
努力する:
find /your-path-here -name "`date +%Y%m%d`-*.txt" -exec mv {} your-path-here/new_file.txt \;
tested on cygwin:
pt@ptphoto7 ~
$ ls -l ./test ; find ./test -name "`date +%Y%m%d`-*.txt" -exec mv {} test/new-file.txt \;
total 3
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 20210810-stuff-and-things.txt
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 20210812-stuff-and-things.txt
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 20210815-stuff-and-things.txt
pt@ptphoto7 ~
$ ls -l ./test
total 3
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 20210810-stuff-and-things.txt
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 20210812-stuff-and-things.txt
-rw-r--r--+ 1 pt None 2 Aug 15 13:49 new-file.txt
pt@ptphoto7 ~
注:新しいファイルが複数のディレクトリに深く含まれていると、正しく機能しません。