简体   繁体   English

尝试使用bash中的捕获组重命名文件

[英]Trying to rename files using capture groups in bash

I have a bunch of image files out of google takeout in folders of the format yyyy-MM-dd/img.jpg - I use phockup to organize my photos and it needs the photos to be in yyyy/mm/dd folders. 我有一堆来自google外卖的图像文件,格式为yyyy-MM-dd / img.jpg-我使用phockup整理照片,并且需要将照片保存在yyyy / mm / dd文件夹中。 I'd like to keep the dates since google already gave me them. 我想保留日期,因为Google已经给了他们。

For example - this folder/image should match 例如-此文件夹/图像应匹配

/2018-07-01/test_img.jpg /2018-07-01/test_img.jpg

and be renamed to 并重命名为

/2018/07/01/test_img.jpg /2018/07/01/test_img.jpg

I've tried using bash together with sed and find to use regex capture groups to move the files, but I don't seem to have had much luck. 我已经尝试过将bash与sed一起使用,并发现使用正则表达式捕获组来移动文件,但是我似乎运气不高。 see below for where I currently am 请参阅以下我当前所在的位置

find . -name "*.jpg" -print0 | sed 'p;s/([0-9]{4})\-([0-9]{2})\-([0-9]{2})\/(.*)/$2\/$3\/$4\/$5/' | xargs -0 -n2 mv

Here is the error I'm getting 这是我遇到的错误

mv: cannot move './2018-07-01/test_img.jpg' to ''$'\\n''./2018-07-01/test_img.jpg': No such file or directory mv:无法将'./2018-07-01/test_img.jpg'移至``$'\\ n''./ 2018-07-01 / test_img.jpg':无此类文件或目录

Which seems odd since the regex capture groups I believe are correct. 自从我认为正则表达式捕获组是正确的以来,这似乎很奇怪。 I'm not sure why it won't rename the files. 我不确定为什么它不会重命名文件。

Here's a bash possibility. 这是一种可能。 Run the script in the directory with the date-named directories. 在带有日期命名目录的目录中运行脚本。 I used a copy command instead of move so you can check the results before deleting the old files. 我使用了复制命令而不是移动,因此可以在删除旧文件之前检查结果。 If you want to use mv instead, at least run it once with echo in front of it for a sanity check. 如果要改用mv,请至少运行一次,并在其前面加上echo以进行健全性检查。

newdir=/home/me/newpics

[[ -d "$newdir"  ]] || mkdir "$newdir"

for dir in *; do
  if [[ -d "$dir" && "$dir" =~ ([0-9]+)-([0-9]+)-([0-9]+) ]]; then
      year=${BASH_REMATCH[1]}
      month=${BASH_REMATCH[2]}
      day=${BASH_REMATCH[3]}

      todir="$newdir/$year"; [[ -d "$todir"  ]] || mkdir "$todir"
      todir+="/$month";      [[ -d "$todir"  ]] || mkdir "$todir"
      todir+="/$day";        [[ -d "$todir"  ]] || mkdir "$todir"

      for file in "$dir/"*.jpg; do
        base=$(basename "$file")
        cp "$file" "$todir/$base"
      done
  fi
done

In addition to my comments above, and that to use {n} occurrences you will need more than basic regex expression, if I understand correctly you only want to match .jpg files with the format, eg /2018-07-01/test_img.jpg , then you will either need to limit the find expression to only find files in the date-formatted directories, or you can have sed only pass along files from those directories. 除了我上面的评论以及使用{n}出现以外,您还需要除基本的正则表达式之外的其他内容,如果我正确理解,则只想将.jpg文件与格式匹配,例如/2018-07-01/test_img.jpg ,那么您将需要限制find表达式以仅在日期格式的目录中查找文件,或者您可以sed只传递那些目录中的文件。 sed provides the ability to only match lines of a given format before attempting the substitution using the form: sed提供了在尝试使用以下格式进行替换之前仅匹配给定格式的行的功能:

sed -r /match/s/find/replace/

( note: the -r option causes sed to use extended regular expressions, check the manual page ( man sed ) to ensure your version supports that option as well, -E is often used for the same purpose) 注意: -r选项使sed使用扩展的正则表达式,请检查手册页( man sed )以确保您的版本也支持该选项, -E通常用于相同目的)

For for your match above, you can use: 对于上述match ,您可以使用:

/^\/[0-9]{4}-[0-9]{2}-[0-9]{2}/

Additionally, the -n option to sed suppresses the default printing of output. 另外, sed-n选项禁止输出的默认打印。 So to craft an expression that only acts on and passes the appropriate files along to xargs , you could use the following sed expression: 因此,要制作仅作用于xargs并将其传递给xargs表达式,可以使用以下sed表达式:

sed -r -n '/^\/[0-9]{4}-[0-9]{2}-[0-9]{2}/s/([0-9]{4})\-([0-9]{2})\-([0-9]{2})\/(.*)/\1\/\2\/\3\/\4/p'

( note: the replacement of '$' with \\ to invoke the wanted backreference and adjusting the backreference number to 1-4 instead of 2-5 , and adding p after the substitution causes sed to print those lines that matched the expression) 注意:\\替换'$'以调用所需的反向引用 ,并将反向引用号调整为1-4而不是2-5 ,并在替换后加上p导致sed打印与表达式匹配的行)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM