[英]osx terminal: renaming files by hierarchy
在OSX Terminal中,我尝试展平文件夹层次结构,但是由于内部文件的名称相同,因此我想使用以前的文件夹名称扩展文件名:
我想从这里得到:
/dirA1/dirB1/file1.ext
/dirA1/dirB2/file1.ext
...
/dirA2/dirB1/file1.ext
...
至
/file1-dirA1-dirB1.ext
/file1-dirA1-dirB2.ext
...
/file1-dirA2-dirB1.ext
...
我试图将重命名( OSX终端中的批处理重命名文件 )与展平( https://unix.stackexchange.com/questions/52814 )结合起来,但是还没有运气...
我将从“查找”开始吗? 但是,如何将目录名称传递给“ mv”?
提前非常感谢您!
一种安全但不是很快的方法是将find
与-exec
一起使用,将每个文件传递给执行替换的shell命令,如下所示:
(cd /path; find . -type f -exec sh -c 'newname=${1:2}; filename=${newname##*/}; dirname=${newname%/*}; newname=$filename-${dirname//\//-}; echo mv "$1" "$newname"' -- {} \;)
使用cd /path
而不是find /path
是为了使我们可以使用该基本目录中的相对路径,这使得创建展平的文件名更加容易。
有关元素的更多说明:
-exec sh -c '...' -- {}
执行sh
,运行-c '...'
指定的命令。 {}
是find
的路径。 -- ...
语法是将参数作为位置参数传递给脚本,可通过$1
, $2
等进行访问。 newname=${1:2}
接受第一个位置参数$1
,并从中提取一个子字符串,跳过前两个字符。 我这样做是因为find .
的输出find .
将具有以./
开头的路径,我们想在将/
替换为-
之前将其删除。 filename=${newname##*/}
提取路径的文件名部分,除去一切从开始到最后一个/
dirname=${newname%/*}
通过删除最后一个/
及其后面的所有内容来提取路径的目录名称部分 ${dirname//\\//-}
替换所有出现的/
有-
如果要删除/
而不是替换,则可以写${dirname//\\//}
此技术是安全的,因为它将与文件名中的任何特殊字符一起使用。 这很慢,因为它为每个文件运行sh
。
完成此步骤后,原始文件的空目录将保留,您可能要删除它们:
find /path -type d -empty -delete
通过将find … -print0
输出输出到while read
循环,您可以安全地处理此问题而无需对每个文件执行sh
,例如:
while IFS= read -r -d '' old; do # read filenames into $old
# -d '' : read until \0
# -r : no backslash escapes
# IFS= : no trimming whitespace
if [[ $old =~ (.*)/(.*)\.(.*) ]]; then # regex with capture groups:
# 1 2 3
set -- "${BASH_REMATCH[@]}"
mv "$old" "${2}-${1//\/}.${3}"
fi
done < <(find . -type f -print 0)
该set -- "${BASH_REMATCH[@]}"
的目的是上面的set -- "${BASH_REMATCH[@]}"
只是为了将包含正则表达式匹配组的数组成员移至位置参数( $1
, $2
等)中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.