sử dụng stat để cung cấp dấu thời gian cho cảm ứng


11

Đang cố gắng OCR một số tài liệu nội bộ (từ một dòng lệnh linux trên chia sẻ windows). Quá trình OCRing được tìm thấy và tôi đã nhầm lẫn thông qua việc sử dụng lệnh find để dẫn các tệp qua vòng lặp một cách chính xác.

Tuy nhiên tôi cần phải giữ dấu thời gian ban đầu để sửa đổi. Tôi hiện đang cố gắng sử dụng stat và chạm như dưới đây:

#!/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

Tất nhiên lệnh cảm ứng thất bại. chạy các lệnh riêng biệt tôi nhận thấy "stat -c" là một cái gì đó dọc theo dòng này:

1334858696

Điều đó giống như không có ngày tôi biết. Tôi cảm thấy như thể tôi đang ở gần nhưng không thể tìm ra cách chuyển đổi ngày tôi có thành phiên bản thân thiện. Đây có phải là một vài giây từ một cái gì đó?


Ngoài ra: việc sử dụng của bạn IFScó vẻ bất thường. Bạn có thực sự muốn phân chia trên backspace ( \b)? Xem unix.stackexchange.com/questions/9496/ Kiếm để biết một số mẹo.
Mikel

Câu trả lời:


17

stat'sđầu ra là dấu thời gian Unix, còn được gọi là giây kể từ Epoch .

Tất cả các lõi GNU chấp nhận ngày cho phép bạn đặt dấu thời gian thay vì tiền tố dấu thời gian bằng dấu @.

Hãy thử cái này

touch -d @$ORIGTS $f

Xem coreutils - Giây kể từ thời đại


ah điều đó giải thích rất nhiều dấu thời gian tôi đã thấy trong linux bây giờ! Cảm ơn rất nhiều
Tim Alexander

8

touchcó thể sử dụng dấu thời gian của tệp bằng -rtùy chọn. Bạn có thể muốn xuất ra một tệp khác (tôi giả sử bên dưới -iflà tệp đầu vào và -oflà tệp đầu ra)

for f in ...; do
    sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
    touch -r $f $f.new
    mv $f.new $f
done

+1 để tránh stat.
l0b0

3

IFS=$(echo -en "\n\b")

Vì bạn đang giả định một vỏ với echo -evà dù sao bạn cũng có bash trong dòng shebang của mình, bạn có thể sử dụng IFS=$'\n\b'. Làm cho backspace một dải phân cách là khá kỳ lạ. Bạn không cần IFScho những gì bạn đang làm gì.

OLDIFS=$IFS
Giáo dục
IFS=$OLDIFS

Lưu ý rằng điều này khôi phục giá trị cũ IFSchỉ khi IFSđược đặt ban đầu. Nếu IFSban đầu không được đặt, bộ này đặt IFSthành chuỗi trống, hoàn toàn khác. Trong ksh, bash hoặc zsh, nếu bạn cần đặt IFStạm thời, bạn có thể viết mã của mình trong một hàm và đặt IFScục bộ cho hàm này. Trong các shell khác, bạn cần cẩn thận về trường hợp chưa đặt.

`find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`

Không bao giờ sử dụng thay thế lệnh trên đầu ra của find.

  • Điều này phân chia đầu ra tại các ký tự trong $IFS. Nếu bạn đặt IFSthành một dòng mới, thì phần này sẽ chia đầu ra ở dòng mới, nhưng bạn vẫn không thể xử lý tên tệp có chứa dòng mới.
  • Không chỉ là kết quả của sự thay thế lệnh được chia thành các từ, mà sau đó mỗi từ được sử dụng như một mẫu hình cầu. Nếu bạn gọi các tệp A[12].pdf, A1.pdfA2.pdf, bạn sẽ kết thúc với A1.pdf A2.pdf A1.pdf A2.pdf. Bạn có thể tắt tính năng toàn cầu bằng set -f(và bật lại bằng set +f), nhưng ở đây (giống như hầu hết thời gian), cách đúng đắn là không sử dụng thay thế lệnh.

Sử dụng -execđối số để find(hoặc nếu hệ thống của bạn có -print0, bạn có thể sử dụng find … -print0 | xargs -0 …thay thế; điều này chỉ hữu ích khi hành động trên nhiều tệp cùng một lúc nếu bạn cần tính di động đối với các hệ thống Linux cổ hoặc các hệ thống OpenBSD hiện tại có -print0nhưng không -exec … {} +).

ORIGTS=`stat -c "%Y" $f`
# [transform $f]
touch -t $ORIGTS $f

Lưu ý rằng bạn đang thiếu dấu ngoặc kép $f(chúng không cần thiết nếu đây là kết quả của việc chia tách và bạn đã không thay đổi IFSkể từ đó và tính năng toàn cầu bị tắt, nhưng thực sự, luôn đặt dấu ngoặc kép trừ khi bạn biết tại sao bạn có thể ' t để chúng trên).

Điều này là vụng về và không di động ( statkhông tồn tại trên tất cả các hệ thống và các đối số của nó là khác nhau trên các hệ thống khác nhau nơi nó tồn tại). touchcó một tùy chọn di động để đặt tệp thành dấu thời gian của tệp khác : touch -r REFERENCE_FILE FILE. Tôi muốn giới thiệu một trong hai cách tiếp cận thay thế:

  • Nếu bạn có thể, trước tiên hãy chuyển đổi tệp gốc thành tệp mới, sau đó gọi touch -rđể đặt ngày của tệp mới và cuối cùng di chuyển tệp mới vào vị trí. Tốt hơn là đảm bảo đầu ra tốt trước khi có bất cứ điều gì xảy ra với đầu vào; mặt khác, nếu quá trình chuyển đổi bị gián đoạn vì bất kỳ lý do nào (ví dụ như mất điện), bạn sẽ mất dữ liệu.
  • Nếu phép chuyển đổi là một hộp đen mà bạn không có quyền kiểm soát, bạn có thể sử dụng touch -rhai lần: một lần để lưu ngày của tệp gốc vào một tệp tạm thời trống (sẽ được tạo tự động), sau đó lại chuyển đổi để khôi phục ngày sử dụng tập tin tạm thời

Như vậy:

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"' {} \;

0

Vì một số lý do tôi đã bỏ lỡ câu trả lời về touch -r; nếu vì một lý do lạ nào đó, bạn không có GNU coreutils ' statnhư trong câu trả lời được chấp nhận cũng như không thể sử dụng touch -r, thì đây là cách lấy dấu thời gian theo touchđịnh dạng thân thiện với giống như 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

Nhưng thực sự, chỉ cần sử dụng touch -r:

% touch foo
% touch -r johnson foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012

0

Tôi đã có cùng một vấn đề, đến từ 'thủ tục di chuyển'.

Trong ví dụ dưới đây orig_file.wavlà tệp có dấu thời gian gốc, trong khi đó processed_file.wavlà tệp có cùng nội dung, nhưng dấu thời gian sai.

TRƯỚC:

localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav

LỆNH:

localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav

SAU:

localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav

GHI CHÚ:

stattrong tích tắc đảo ngược cung cấp cho bạn dấu thời gian tạo của tệp gốc dưới dạng thời gian unix epoch (tính bằng giây). @ Từ coreutils chuyển đổi nó thành một ngày iso datecó thể hiểu và định dạng lại với YYYYMMDDHHmm.SS để touchcó thể hiểu nó. Tôi đặt datelệnh vào $ (), tương đương với các dấu đảo ngược, vì chúng không thể được sử dụng lại trong cùng một lệnh.


(1) Điều này có vẻ gần giống hệt như câu trả lời của Nicholas Riley nhưng phức tạp hơn. Tại sao mọi người muốn sử dụng cái này hơn là cái kia (hoặc, tốt hơn, câu trả lời của glenn jackman , sử dụng touch -r)? (2)  stat có thể được đưa vào $(…); chúng có thể được sử dụng nhiều lần trong một lệnh.
G-Man nói 'Phục hồi Monica'

Khác với câu trả lời của anh ấy bằng cách sử dụng thời gian sửa đổi thay vì tạo thời gian, bạn dường như là chính xác. Tôi không nhận thấy câu trả lời khác này. Bạn có thể bỏ phiếu của tôi.
dominikz

Chà, nếu bạn hỏi tôi thì chẳng có gì vui cả. :-)
G-Man nói 'Phục hồi Monica'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.