テキストファイルにリストされているすべてのファイル(約300万行、ソースとターゲットの2列)をコピーし、新しいファイル名を使用するスクリプトを作成しようとしています。
path/to/source/directory/filename.pdf path/to/destination/directory/Newfilename.pdf
path/to/source/directory/filename2.pdf path/to/destination/directory/Newfilename2.pdf
path/to/source/directory/filename3.pdf path/to/destination/directory/Newfilename3.pdf
...
すべてのファイルはPDF形式で、Newfilename.pdfは同じソースPDFファイルの新しいファイル名です。
また、ファイルをコピーし、ターゲットファイル名に次の情報を追加したいと思います。
From:
Newfilename.pdf
To:
Newfilename_yyyyMMddHHmmss.pdf (e.g. Newfilename_20200225095823.pdf)
各ファイルの実際のコピー実行日時はどこにありますかyyyyMMddHHmmss
?これはすべてのファイルに対して同じ形式であるため、ターゲットファイルはセカンダリ名を使用してコピーされます。
path/to/destination/directory/Newfilename_20200225095823.pdf
path/to/destination/directory/Newfilename2_20200225095824.pdf
path/to/destination/directory/Newfilename3_20200225095830.pdf
...
私はコマンドを処理する知識が不足しています。私が取り組んでいるアイデアは次のとおりです。
#!/bin/bash
filename=$1
while read -r source destination; do
# reading each value
cp -p source destination
done < $filename
しかし、同様の出版物を読んだことがあります。パフォーマンスのため、ファイルやパイプから読み込むと、ループと読み込みが非常に遅くなります。これは、組み込みの読み取りシェルが一度に1文字ずつ読み取られるためです。引用するここ。
より良いソリューションを使用すると、どのようにこれを達成できますか?
ご協力ありがとうございます。
答え1
パフォーマンスの面を除いて、問題の最初の部分はbashの変数操作方法を使用して解決できます。
timestamp="$(date +%Y%m%d%H%M%S)"
while read -r source destination; do
newname="${destination/%.pdf/_$timestamp.pdf}"
cp -p "$source" "$newname"
done < "$filename"
タイムスタンプがスクリプトが呼び出された瞬間ではなく「コピー瞬間」の場合、呼び出しはdate
ループ内に配置する必要があります。
while read -r source destination; do
timestamp="$(date +%Y%m%d%H%M%S)"
newname="${destination/%.pdf/_$timestamp.pdf}"
cp -p "$source" "$newname"
done < "$filename"
修正する:@Jetchiselが指摘したように、bash
v4.2以降、commandを使用して日付形式を指定する機能が組み込まれており、printf
外部コマンドを呼び出すdate
必要はありません。
while read -r source destination; do
printf -v timestamp '%(%Y%m%d%H%M%S)T'
newname="${destination/%.pdf/_$timestamp.pdf}"
cp -p "$source" "$newname"
done < "$filename"