重命名文件名末尾带有日期修改时间戳的文件?


14

因此,例如,我有一个包含一堆文件的目录,例如g.txt,其中g.txt的最后修改时间为2012年6月20日。

如何将所有文件(如g.txt)重新命名为最后修改日期为2012年6月20日的文件?

Answers:


13

快速且肮脏的Bash一线式将当前目录中的所有(globbed)文件从重命名filename.txtfilename.txt-20120620

for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done

我敢肯定,一个有进取心的Bash书呆子会发现一些突破的方法。:)

显然,这并没有实现所需的功能,例如检查文件是否已经具有结束日期的内容。


2
+1,看起来不错。您可以通过使用'-'作为mv的第一个arg使其更加健壮。针对filenaes与begining卫士' - '
中科院

5
那是什么样的date实现?我的GNU date似乎不处理输入。
manatwork

的coreutils 8.4 RHEL 6.
jgoldschrafe

2
@jgoldschrafe,确定代码适合您吗?pastebin.com/nNYubf3A
manatwork 2012年

5
抓好杂技。我的GNU日期8.13也不支持从stdin读取。它确实支持将文件的修改时间与“ -r”一起使用-例如“ date +%Y%m%d -r $ f”,因​​此在这种特殊情况下甚至不需要stat。
cas 2012年

18

这是goldschrafe的单线版本:

  • 不使用统计
  • 与早期版本的GNU日期一起使用
  • 正确处理文件名中的任何空格
  • 还可以处理以短划线开头的文件名

    for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done


1
您应该这样做,date -r "$f" +%Y%m%d否则POSIXLY_CORRECT在环境中将不起作用。通常,选项应该放在其他参数之前。
斯特凡Chazelas

这应该是“正确答案”
invalidusername

当然,您不需要大括号"${f}"
G-Man说'Resstate Monica''Mar

但是您如何使它成为我们的前缀,例如“ Ymd-filename”?
timebandit

2

必需的zsh单线(不计算一次性组件的一次性加载):

zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'

我们使用stat来自zsh/stat模块的内置zmv函数,并使用函数来重命名文件。还有一个额外的功能,它将日期(如果有的话)放在扩展名之前。

zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'

1

据我了解,我们事先不知道修改日期是什么。因此,我们需要从每个文件中获取文件,格式化输出并以某种方式重命名每个文件,以使其在文件名中包含修改日期。

您可以将此脚本另存为“ modif_date.sh”,并使其可执行。我们使用目标目录作为参数来调用它:

modif_date.sh txt_collection

其中“ txt_collection”是目录的名称,我们拥有要重命名的所有文件。

#!/bin/sh

# Override any locale setting to get known month names
export LC_ALL=c
# First we check for the argument
if [ -z "$1" ]; then
    echo "Usage: $0 directory"
    exit 1
fi

# Here we check if the argument is an absolute or relative path. It works both ways
case "${1}" in
  /*) work_dir=${1};;
  *) work_dir=${PWD}/${1};;
esac

# We need a for loop to treat file by file inside our target directory
for i in *; do
    # If the modification date is in the same year, "ls -l" shows us the timestamp.
    # So in this case we use our current year. 
    test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'`
    case ${test_year} in *:*) 
        modif_year=`date '+%Y'`
        ;;
    *)
        modif_year=${test_year}
        ;;
    esac
    # The month output from "ls -l" is in short names. We convert it to numbers.
    name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'`
    case ${name_month} in
            Jan) num_month=01 ;;
            Feb) num_month=02 ;;
        Mar) num_month=03 ;;
        Apr) num_month=04 ;;
        May) num_month=05 ;;
        Jun) num_month=06 ;;
        Jul) num_month=07 ;;
        Aug) num_month=08 ;;
        Sep) num_month=09 ;;
        Oct) num_month=10 ;;
        Nov) num_month=11 ;;
        Dec) num_month=12 ;;
        *) echo "ERROR!"; exit 1 ;;
    esac
    # Here is the date we will use for each file
    modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year}
    # And finally, here we actually rename each file to include
    # the last modification date as part of the filename.
    mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}"
done

1
阅读stat(1)的手册页,以了解如何将脚本缩小约3/4 ...以上大部分内容是在重新发明轮子。特别是'stat -c%Y'将为您提供自纪元(1970-01-01 00:00:00)以来文件的修改时间,以秒为单位。然后可以将其用作date(1)的输入,以根据需要格式化时间戳。请参阅上面的jgoldschrafe的答案作为示例。
cas

@CraigSanders好处是,此脚本可在Linux以外的操作系统下运行,这些操作系统具有不同的stat实用程序或完全没有。
吉尔(Gilles)'所以

请注意,解析的输出ls是不可靠的。在某些Unix变体上,用户名和组名可以包含空格,这会导致日期列的对齐方式偏离。
吉尔(Gilles)'所以

@giles:是的,但是任何明智的人:-)都会在任何非Linux系统上安装GNU coreutils(以及所有其他GNU工具)。这是最简单的方法,不仅可以获得一套好的用户界面工具,而且也可以得到一套一致的工具,而与底层内核无关。
cas

1
(续)(5)另一个缺陷:它假设任何日期/时间显示ls 一个日期和时间(而不是一个日期和年)必须是在本年度。这不是真的。过去六个月了;可能是上一年(例如,2016年9月27日至2016年12月31日在过去六个月之内)。(6)冒名顶格雷格的Wiki(@Gilles已经引用)的风险,包含换行符和空格的文件名可能会导致失败。…(续)
G-Man说'Resstate Monica''Mar

0

这是cas的单线版本(基于goldschrafe的单线),并扩展了幂等性

即扩展到具有日期时间的前缀文件,并且仅对那些没有日期时间前缀的文件进行扩展。

用例:如果您将新文件添加到目录中,并想为尚未添加文件的文件添加日期时间前缀,则很有用。

for f in * ; do
  if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
    mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
  fi;
done

如果您的文件时间戳是固定的,并且是jpeg,则您可能希望冷杉使用EXIF数据对其进行修复:for f in *.jpg ; do jhead -ft "$f" ; done来源:unix.stackexchange.com/a/290755/9689
Grzegorz Wierzowiecki,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.