一部のドキュメントをその場でOCRしようとしています(Windows共有のLinuxコマンドラインから)。 OCR処理のプロセスはfindであり、findコマンドを使用してファイルをループに正しくパイプすることで混乱しています。
ただし、変更のために元のタイムスタンプを保持する必要があります。私は現在、以下のようにstatとtouchを使用しようとしています:
#!/bin/bash
OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for f in `find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`
do
ORIGTS=`stat -c "%Y" $f`
Sudo /opt/ABBYYOCR9/abbyyocr9 -rl English -pi -if $f -f PDFA -paemImageOnText -pafpr original -of $f
touch -t $ORIGTS $f
done
IFS=$OLDIFS
もちろんタッチコマンドは失敗します。コマンドを個別に実行すると、 "stat -c"が次のようになります。
1334758696
それは私が知らない日付のようなものです。近くにいるような気がしますが、日付をタッチフレンドリーなバージョンに変換する方法がわかりません。何かからの秒の形ですか?
stat's
出力は、Unixタイムスタンプであり、エポックからの秒数とも呼ばれます。
すべてのGNU日付を受け入れるcoreutilsでは、タイムスタンプの前に@
を付けることにより、タイムスタンプを置くことができます。
だからこれを試してください
touch -d @$ORIGTS $f
coreutils-エポックからの秒数 を参照してください
touch
は、-r
オプションを使用してファイルのタイムスタンプを使用できます。別のファイルに出力したい場合があります(以下では、-if
が入力ファイルで、-of
が出力ファイルであると想定しています)
for f in ...; do
Sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
touch -r $f $f.new
mv $f.new $f
done
IFS=$(echo -en "\n\b")
echo -e
を含むシェルを想定していて、とにかくシバン行にbashがあるので、IFS=$'\n\b'
を使用できます。バックスペースをセパレーターにするのは奇妙です。とにかくあなたがしていることのためにIFS
は必要ありません。
OLDIFS=$IFS
…IFS=$OLDIFS
これにより、IFS
が最初に設定された場合にのみ、IFS
の古い値が復元されます。 IFS
が最初に設定されていなかった場合、これはIFS
を完全に異なる空の文字列に設定します。 ksh、bash、またはzshでは、IFS
を一時的に設定する必要がある場合は、コードを関数に記述し、IFS
をこの関数に対してローカルにすることができます。他のシェルでは、未設定のケースに注意する必要があります。
`find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`
find
の出力でコマンド置換を使用しないでください。
$IFS
の文字で出力を分割します。 IFS
を改行に設定すると、出力は改行で分割されますが、改行を含むファイル名は処理できません。A[12].pdf
、A1.pdf
、A2.pdf
と呼ばれるファイルを作成すると、最終的にはA1.pdf A2.pdf A1.pdf A2.pdf
になります。 set -f
を使用して(そしてset +f
を使用して再度)グロブをオフにすることができますが、ここでは(ほとんどの場合)、コマンド置換を使用しないのが正しい方法です。-exec
引数をfind
に使用します(または、システムに-print0
がある場合は、代わりにfind … -print0 | xargs -0 …
を使用できます。これは、複数のファイルを同時に操作する場合にのみ役立ちます-print0
はあるが-exec … {} +
はない古いLinuxシステムまたは現在のOpenBSDシステムへの移植性が必要です。
ORIGTS=`stat -c "%Y" $f` # [transform $f] touch -t $ORIGTS $f
$f
の前後に二重引用符がないことに注意してください(これらが分割の結果であり、その後IFS
を変更しておらず、グロビングがオフになっている場合は不要ですが、実際には、それらをオンのままにできない理由がわからない限り、常に二重引用符を付けてください)。
これは不格好で移植性がありません(stat
はすべてのシステムに存在するわけではなく、その引数は、存在するさまざまなシステム間で異なります)。 touch
には、ファイルを別のファイルのタイムスタンプに設定するポータブルオプションがあります:touch -r REFERENCE_FILE FILE
。代わりに次の2つの方法のいずれかをお勧めします。
touch -r
を呼び出して新しいファイルの日付を設定し、最後に新しいファイルを適切な場所に移動します。入力に何かが起こる前に、出力に問題がないことを確認することをお勧めします。そうしないと、何らかの理由(停電など)で変換が中断された場合、データが失われます。touch -r
を2回使用できます。1回は元のファイルの日付を空の一時ファイル(自動的に作成されます)に保存し、次に一時ファイルを使用して日付を復元する変換。したがって:
find /mnt/library/Libra/Libra/Ashfords -name '*.pdf' \
-exec sh -c 'transform "$0" to "$0.tmp" && touch -r "$0" "$0.tmp" && mv -f "$0.tmp" "$0"' {} \;
何らかの理由で、touch -r
に関する回答を逃しました。何らかの奇妙な理由で、GNU coreutils 'stat
が承認された回答のようにないか、touch -r
を使用できない場合は、touch
フレンドリーな形式で、BSD風のstat
を使用します。
% /usr/bin/stat -f '%Sm' johnson
Oct 23 22:51:00 2012
% /usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson
201210232251.00
% touch foo
% touch -t $(/usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson) foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012
ただし、実際にはtouch -r
を使用してください。
% touch foo
% touch -r johnson foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012
「映画製作」プロセスから来る同じ問題がありました。
以下の例では、_orig_file.wav
_は元のタイムスタンプを持つファイルですが、_processed_file.wav
_は同じ内容のファイルですが、タイムスタンプが間違っています。
前:
_localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav
_
コマンド:
localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav
後:
_localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav
_
ノート:
逆ティックのstat
は、元のファイルの作成タイムスタンプをUNIXエポック時間(秒単位)で示します。 coreutilsの@は、date
がそれを理解できるように、touch
がYYYYMMDDHHmm.SSを使用して再フォーマットできるISO日付に変換します。 date
コマンドを$()に入れました。これは、同じコマンドで再利用できないため、逆ティックに相当します。