linux - Bash linux,JPG 图像的小时、分钟和秒

标签 linux bash image

我正在尝试获取 JPG 格式图像的完整日期。我想要获取的格式是 14:25:38(时:分:秒)。

我尝试了以下命令:

$ stat -c %y DSC_0002.JPG | sed 's/^\([0-9\-]*\).*/\1/'
=> 2017-05-19  -Not that way

$ file DSC_0002.JPG
=> DSC_0002.JPG: JPEG image data, Exif standard: [TIFF image data, little-endian, direntries=11, manufacturer=NIKON CORPORATION, model=NIKON D5200, orientation=upper-left, xresolution=180, yresolution=188, resolutionunit=2, software=Ver.1.01 , datetime=2017:05:19 13:30:34, GPS-Data], baseline, precision 8, 6000x4000, frames 3

最后一个 (file DSC_0002.JPG) 命令显示 datetime=2017:05:19 13:30:34,但我只需要获取 13 :30:34

最好不要使用 Linux bash 之外的附加组件或程序。

非常感谢您的帮助。

最佳答案

我的 2 美分...

因为 exif 是我工作的重要组成部分,而且因为我已经花了很多时间构建自己的脚本,所以是时候制作一个小板凳了。

使用 获取jhead 的结果| :

这里使用 jhead 因为这是我的首选。进一步了解原因...

DateTime=$(jhead -nofinfo DSC_0002.JPG)
DateTime=${DateTime#*Date/Time*: }
DateTime=${DateTime%%$'\n'*}

这是最快的方法(比使用 bash regex 快很多)!

echo $DateTime 
2011:02:27 14:53:32

不同的方式

使用至少 4 种不同的工具可以查询 jpeg 文件以了解他的日期:

  1. file magic file 识别命令可以轻松查询任何文件以确定文件的性质并打印更多信息。

    file  DSC_0002.JPG 
    DSC_0002.JPG: JPEG image data, Exif standard: [TIFF image data, big-endian,
    direntries=10, manufacturer=CANIKON, model=CANIKON AB12, orientation=upper-
    left, xresolution=168, yresolution=176, resolutionunit=2, software=Ver.1.00
    , datetime=2011:02:27 14:53:32], baseline, precision 8, 3872x2592, frames 3
    

    file 从 jpeg 文件打印尺寸、分辨率和日期时间。

  2. jhead 是一个jpeg 的header 专用工具:

    jhead DSC_0002.JPG 
    File name    : DSC_0002.JPG
    File size    : 4940925 bytes
    File date    : 2011:02:27 14:53:32
    Camera make  : CANIKON
    Camera model : CANIKON AB12
    Date/Time    : 2011:02:27 14:53:32
    Resolution   : 3872 x 2592
    Flash used   : No
    Focal length : 55.0mm  (35mm equivalent: 82mm)
    Exposure time: 0.0080 s  (1/125)
    Aperture     : f/5.6
    ISO equiv.   : 180
    Whitebalance : Auto
    Metering Mode: pattern
    JPEG Quality : 97
    
  3. identifyImageMagick 包的一部分,它是一种用于位图图像的通用工具...(由于过去和整体性能中的一些安全漏洞,这不是我个人的选择)。

    identify DSC_0002.JPG 
    DSC_0002.JPG JPEG 3872x2592 3872x2592+0+0 8-bit sRGB 4.941MB 0.010u 0:00.020
    identify -format "%[EXIF:DateTime]\n" DSC_0002.JPG 
    2011:02:27 14:53:32
    
  4. exiftool 是使用libimage 的专用工具。

    exiftool DSC_0002.JPG
    ExifTool Version Number         : 9.74
    File Name                       : DSC_0002.JPG
    Directory                       : .
    File Size                       : 4.7 MB
    File Modification Date/Time     : 2011:02:27 14:53:32+01:00
    File Access Date/Time           : 2017:06:05 08:40:26+02:00
    File Inode Change Date/Time     : 2017:06:05 08:40:04+02:00
    File Permissions                : rw-r--r--
    File Type                       : JPEG
    MIME Type                       : image/jpeg
    Exif Byte Order                 : Big-endian (Motorola, MM)
    ...
    Modify Date                     : 2011:02:27 14:53:32
    ...
    Thumbnail Image                 : (Binary data 8965 bytes, use -b option to extract)
    Circle Of Confusion             : 0.020 mm
    Depth Of Field                  : 15.07 m (8.58 - 23.65)
    Field Of View                   : 24.7 deg (5.50 m)
    Focal Length                    : 55.0 mm (35 mm equivalent: 82.0 mm)
    Hyperfocal Distance             : 26.80 m
    Light Value                     : 11.1
    

    这个的默认输出是 185 行长度,我已经减少了很多。

  5. bash 根据要求,因为 Toby Speight推荐to not doing this :

    FDate=;while IFS= read -d  $'\0'  -n 1024 raw;do
      [ "$raw" ] && \
      [ -z "${raw#[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]}" ] &&
      FDate=$raw && break
    done <DSC_0002.JPG
    echo $FDate
    2011:02:27 14:53:32
    

    好的,这是一个非常完美的功能:无论字段名如何,都会考虑在文件中找到的第一个日期。

小板凳

由于目标是提取 exif 信息的日期时间部分,因此工作台只会执行此操作。

time for i in {1..100};do ... done >/dev/null
export TIMEFORMAT="R:%4R u:%4U s:%4S"

像这样(从快到慢):

# quicker: jhead
time for i in {1..100};do jhead DSC_0002.JPG ;done >/dev/null
R:0.115  u:0.000  s:0.028

# 2nd: file
time for i in {1..100};do file DSC_0002.JPG; done >/dev/null
R:0.226  u:0.000  s:0.044

# 3nd: pure bash
time for i in {1..100};do 
    while IFS= read -d  $'\0' -n 1024 raw ;do
        [ "$raw" ] && 
        [ -z "${raw#[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]}" ] &&
         ftim=$raw && break
      done <DSC_0002.JPG
   done >/dev/null
R:0.393  u:0.380  s:0.012

# 4nd: best dedicated: exiftool
time for i in {1..100};do exiftool -time:CreateDate DSC_0002.JPG ;done >/dev/null
R:14.921  u:13.064  s:0.956

# slower: imagemagick's identify
time for i in {1..100};do identify -format "%[EXIF:DateTime]\n" DSC_0002.JPG ;done >/dev/null
R:21.609  u:15.712  s:5.060

对不起,我同意 Toby Speight : 在 pure bash 中执行此操作并不是一个好主意!

设置文件日期

在纯 bash 下进行日期操作非常容易,但要处理文件日期。为此,我要求我的系统将所有照片文件的日期时间设置为在 exif 中找到的创建日期。

为此,exiftool 提供了一种特定的语法:

exiftool '-FileModifyDate<DateTimeOriginal /path/to/myphotos

jhead也是:

jhead -q -ft /path/to/myphotos/*.JPG

这将根据 exif 信息中的创建日期设置所有创建文件日期。完成后,您可以使用标准工具进行文件系统查询:

ls -l DSC_0002.JPG
stat DSC_0002.JPG

find /path/to/myphotos -type f -name 'DSC*JPG' -mtime +400 -mtime -410 -ls

等等……

关于linux - Bash linux,JPG 图像的小时、分钟和秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44320642/

相关文章:

linux - xterm 中 vim 的功能键

mysql - 使用 bash 脚本将文本添加到 xls 文件

php - 为什么 COMPOSER_HOME 是空的?

css - 在 div 标签中垂直居中图像

WPF 从 RESX 文件中获取图像

linux - mmap 与 malloc : strange performance

linux - 如何以编程方式在 linux 系统中的路径中创建文件以及丢失目录?

linux - 仅使用 Linux Shell 编辑文件

bash - 命令输出和字符串比较

image - Web 上可缩放矢量图形的最佳文件格式?