bash:根据祖父目录名称重命名不确定的子文件夹中的文件
bash: rename files in indeterminate sub-subfolders based on grandparent directory name
这里的 Bash 新手试图将文件夹的名称插入到该文件夹内的某些文件中。
问题是这些文件都在主目录的子文件夹的子文件夹中,每个级别的名称都不一样。
例如,主文件夹 interviews
可能包含 John Doe
,在 John Doe
下是目录 Images
和文件 Screenshot.jpg
。但也可能有 John Smith
和文件夹 Etc
,其中 12_Screenshot 2.jpg
.
我想重命名所有这些包含 Screenshot
的文件,在文件名前插入 John Doe
或 John Smith
。
我尝试改编我发现的几个脚本并从 interviews
目录运行它们:
for i in `ls -l | egrep '^d'| awk '{print }'`; do find . -type f -name "*Screenshot*" -exec sh -c 'mv "[==]" "${i}[==]"' '{}' \; done
之后终端给出插入符提示,就好像我遗漏了什么一样。我也试过了
find -regex '\./*' -type d -exec mv -- {}/*/*Screenshot* {}/{}.jpg \; -empty -delete
哪个returnsfind: illegal option -- r
第二个理论上将文件移动到父文件夹这一事实不是问题,因为无论如何我最终都必须这样做。
对于当前工作目录中的每个目录,递归查找包含字符串 "screenshot" 的文件(由于 OSX 不区分大小写)。将找到的路径拆分为父部分(始终至少以 './' 形式存在)和文件名,产生两行,第一行是原始文件路径,第二行是原始文件夹 + 修改后的目标文件名。使用两个参数通过 xargs 执行 mv 命令(用换行符分隔以允许路径中有空格):
for i in `ls -l | sed -n '/^d\([^[:space:]]\+[[:space:]]\+\)\+\([^[:space:]]\+\)$/s///p'`; do
find "$i" -type f -iname "*Screenshot*" \
| sed -n '\!^\(\([^/]\+/\)\+\)\([^/]\+\)$!s!!\n'$i'!p' \
| xargs -d '\n' -n 2 mv;
done
缺点:OSX 上的 xargs 不知道 --no-运行-if-empty,因此对于不包含带有 "screenshot" 字符串的文件的目录调用空 mv .需要添加适当的选项(无法访问 OSX 手册页)或 xargs ... 2>&/dev/null 忽略所有错误...
以下脚本将按需要工作:
dir=
find $dir -name "*Screenshot*" -type f | while read file
do
base=$(basename $file)
dirpath=$(dirname $file)
extr=$(echo $file | awk -F/ '{print $(NF-2)}') #extracts the grandparent directory
mv $file $dirpath/$extr-$base
done
如@loneswap 所述,这必须作为脚本调用。因此,如果您的主目录是 mainDir
,那么您可以这样调用它...
./script mainDir
这里的 Bash 新手试图将文件夹的名称插入到该文件夹内的某些文件中。
问题是这些文件都在主目录的子文件夹的子文件夹中,每个级别的名称都不一样。
例如,主文件夹 interviews
可能包含 John Doe
,在 John Doe
下是目录 Images
和文件 Screenshot.jpg
。但也可能有 John Smith
和文件夹 Etc
,其中 12_Screenshot 2.jpg
.
我想重命名所有这些包含 Screenshot
的文件,在文件名前插入 John Doe
或 John Smith
。
我尝试改编我发现的几个脚本并从 interviews
目录运行它们:
for i in `ls -l | egrep '^d'| awk '{print }'`; do find . -type f -name "*Screenshot*" -exec sh -c 'mv "[==]" "${i}[==]"' '{}' \; done
之后终端给出插入符提示,就好像我遗漏了什么一样。我也试过了
find -regex '\./*' -type d -exec mv -- {}/*/*Screenshot* {}/{}.jpg \; -empty -delete
哪个returnsfind: illegal option -- r
第二个理论上将文件移动到父文件夹这一事实不是问题,因为无论如何我最终都必须这样做。
对于当前工作目录中的每个目录,递归查找包含字符串 "screenshot" 的文件(由于 OSX 不区分大小写)。将找到的路径拆分为父部分(始终至少以 './' 形式存在)和文件名,产生两行,第一行是原始文件路径,第二行是原始文件夹 + 修改后的目标文件名。使用两个参数通过 xargs 执行 mv 命令(用换行符分隔以允许路径中有空格):
for i in `ls -l | sed -n '/^d\([^[:space:]]\+[[:space:]]\+\)\+\([^[:space:]]\+\)$/s///p'`; do
find "$i" -type f -iname "*Screenshot*" \
| sed -n '\!^\(\([^/]\+/\)\+\)\([^/]\+\)$!s!!\n'$i'!p' \
| xargs -d '\n' -n 2 mv;
done
缺点:OSX 上的 xargs 不知道 --no-运行-if-empty,因此对于不包含带有 "screenshot" 字符串的文件的目录调用空 mv .需要添加适当的选项(无法访问 OSX 手册页)或 xargs ... 2>&/dev/null 忽略所有错误...
以下脚本将按需要工作:
dir=
find $dir -name "*Screenshot*" -type f | while read file
do
base=$(basename $file)
dirpath=$(dirname $file)
extr=$(echo $file | awk -F/ '{print $(NF-2)}') #extracts the grandparent directory
mv $file $dirpath/$extr-$base
done
如@loneswap 所述,这必须作为脚本调用。因此,如果您的主目录是 mainDir
,那么您可以这样调用它...
./script mainDir