我有一个深层嵌套的文件夹结构,其中有数百个名为data.log
.我需要一个脚本来根据每个data.log
文件所在的父文件夹的名称重命名这些文件,然后将重命名的文件移动到定义的目标文件夹。原始data.log
文件应保留在原处。
例子:
该文件/opt/slm/data/system/amd-823723/data.log
需要重命名为amd-823723
,然后移动到/opt/slm/output/
,从而使原始data.log
文件保留在原处。
答案1
#!/bin/bash
OUTDIR=/opt/slm/output/
find /opt/slm/data -name data.log |
while read FILE; do
OUTFILE="$(basename "$(dirname "$FILE")")"
cp -p "$FILE" "$OUTDIR$OUTFILE"
done
答案2
和zsh
:
autoload zmv # best in ~/.zshrc
zmv -n -C '**/(*)/data.log' '/opt/slm/output/$1'
如果满意,请删除-n
(用于试运行)。
这-C
是为了复制(与改名/ mv
)即使你的描述说改名,看起来你想要复制将文件改为output
目录中。
答案3
使用find -exec
:
find /opt/slm/data -name data.log -exec sh -c '
TARGET="/opt/slm/output/$(basename "$(dirname "$1")")";
cp -i "$1" "$TARGET"
' find-sh {} \;
答案4
该解决方案仅适用于不带空格的目录名称:
#!/bin/bash
targetDir=/opt/slm/output/
for myPath in `find /opt/slm/data/system |grep "data.log$"`
do
newName = `echo "$myPath" |awk 'BEGIN {FS="/"} /data.log/ {print $(NF-1)}'`
cp "$myPath" ${targetDir}"${newName}"
done
事实上,所有给定的解决方案,包括我的,都是错误的,因为它们会导致信息丢失对于目录:
a/a/data.log
a/data.log
b/a/data.log
所有文件的名称均为“a”,并将被最后一个文件 b / a / data.log 覆盖
python3中的示例程序解决了这个问题:
import os
for x in (os.walk('/opt/slm/data/system')):
if x[2] == ['data.log']:
newName=x[0].replace('/','#').replace(' ','_')
os.system('cp "'+str(x[0])+'/data.log" /opt/slm/output/'+str(newName))
创建包含完整路径和 _ 字符而不是空格的名称:
#opt#slm#data#system#dirname
当然,命名和路径必须适应您的需要。