ソースとターゲットの値を含む大容量のテキストファイルからファイルをコピーする方法は?

ソースとターゲットの値を含む大容量のテキストファイルからファイルをコピーする方法は?

テキストファイルにリストされているすべてのファイル(約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が指摘したように、bashv4.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"

おすすめ記事