将目录名称添加到前缀文件名中

将目录名称添加到前缀文件名中

我有大约 100 个目录,例如:

  • 步行,
  • 写作,
  • 跳舞,
  • 游泳。

每个目录都包含一组文件。

我想将目录的前缀名称添加到其文件的文件名中。

例如:

writing :
0ZPQl5QUvo0_000202_000212.mp4  
AFV8x8ezN8g_000016_000026.mp4  
-HutuMqTAPw_000275_000285.mp4 
qtvsw6h3yQo_000228_000238.mp4  
Ub0rc6U6nfI_000100_000110.mp4

变成:

writing :
writing_0ZPQl5QUvo0_000202_000212.mp4  
writing_AFV8x8ezN8g_000016_000026.mp4  
writing_-HutuMqTAPw_000275_000285.mp4 
writing_qtvsw6h3yQo_000228_000238.mp4  
writing_Ub0rc6U6nfI_000100_000110.mp4

我怎样才能做到这一点?

答案1

这是脚本的一个稍微改进的版本 - 主要区别在于

  • 使用 shell glob*代替$(ls)- 参见Bash 陷阱 #1

  • 引用任何变量扩展(允许文件名带有空格或其他奇怪字符 - 参见Bash 陷阱 #2

  • mv标记使用GNU 扩展的选项的结束--- 这使得它也能处理以连字符开头的文件名

所以

for d in *; do 
  [[ -d "$d" ]] && cd "$d" || continue
  for f in *.mp4; do 
    echo mv -v -- "${f}" "${d}_${f}"
  done
  cd -
done

或者,更便携的是,你可以循环./*.mp4以避免前导连字符 - 但随后你必须在mv

for d in *; do 
  [ -d "$d" ] && cd "$d" || continue
  for f in ./*.mp4; do 
    echo mv -v "${f}" "${d}_${f#./}"
  done
  cd -
done

无论哪种情况,一旦您确定它按预期工作,请删除echo(如果您愿意,还可以删除)。-v

答案2

使用以下脚本可以解决该问题:

for i in $(ls); do                                                 
  if [ -d $i ]; then                      
     fname=${i##*/}                 
     echo $fname                           
     cd $i                                       
     for z in *.mp4; do               
       echo $z  
       cp $z ${fname}_${z}
       rm $z                   
     done                                        
     cd ..                                         
  fi                                              
done

答案3

假设你位于包含所有这些目录的目录中dancingwriting命令

for folder in $(find -mindepth 1 -type d); do
  cd $folder
  PRE=${folder#./}
  for file in *; do
    mv "$file" "${PRE}_$file"
  done
  cd ..
done

将实现您想要的效果。我测试过,即使文件名包含空格或换行符,它也能正常工作。但是,如果文件夹名称中包含此类字符,则不起作用,例如walking slowly

编辑:上述代码无法处理文件夹名称中的空格或换行符。要解决此问题,请使用修改后的代码

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    PRE=${folder#./}
    for file in *; do
      mv "$file" "${PRE}_$file"
    done
    cd ..
  fi
done

编辑2:如果文件名以-(破折号)开头,命令可能会将其解释为选项。要处理前导破折号,请在命令及其参数--之间插入一个。这告诉停止扫描选项。mvmv

所以最终的代码是

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    for file in *; do
      mv -- "$file" "${folder}_$file"
    done
    cd ..
  fi
done

答案4

使用findprename

find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'

删除-n实际重命名文件的选项,而不仅仅是打印文件如何重命名。

相关内容