web-dev-qa-db-ja.com

親フォルダー名を追加してファイルの名前を変更する

ファイル名をその親フォルダー名、追加現在の名前の前のフォルダー名に変更します。

例えば:

フォルダー構造

SOCH NC KT 633-ROYAL BLUE-MULTI
|
| 1.jpg
|
| 2.jpg
|
| 3.jpg

期待される結果

SOCH NC KT 633-ROYAL BLUE-MULTI
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg

SOCH NC KT 710-BLACK-MULTI

誰もこれを.shファイルでどのように行うことができるかアドバイスできますか?操作を行うためのユーティリティはありますか?

5
Neo

小さなpythonスクリプトで、ファイルの名前を変更再帰的に(フォルダーとサブフォルダー):

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for f in files:
        shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)

使い方

  • スクリプトを空のファイルにコピーし、rename_files.pyとして保存します
  • ディレクトリを引数として実行します。

    python3 /path/to/rename_files.py /directory/with/files
    

注意

いつものように、まずサンプルを試してください!

説明

スクリプト:

  • ディレクトリを調べて、ファイルを探します。
  • ファイルが見つかった場合、区切り文字「/」でファイルへのパスを分割し、行の最後(親のフォルダー名)を保持して、ファイル名の前に貼り付けます。

    root.split("/")[-1]
    
  • その後、ファイルを名前を変更したファイルに移動します。

    shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
    
5
Jacob Vlijm

bashから少し助けを借りて、シェル(mv)のみを使用する:

#!/bin/bash
shopt -s globstar  ##globstar will let us match files recursively
files=( /foo/bar/**/*.jpg )  ##Array containing matched files, mention where to search and what files here
for i in "${files[@]}"; do 
    d="${i%/*}"  ##Parameter expansion, gets the path upto the parent directory
    d_="${d##*/}"  ##gets the name of parent directory
    f="${i##*/}"  ##gets the file name
        echo mv "$i" "$d"/"${d_}""$f"  ##renaming, remove echo after confirming what will be changed and you are good
done

例:

$ shopt -s globstar
$ files=( /foo/bar/**/*.jpg )
$ for i in "${files[@]}"; do d="${i%/*}"; d_="${d##*/}"; f="${i##*/}"; echo mv "$i" "$d"/"${d_}""$f"; done
mv /foo/bar/KT/633-ROYAL/4.jpg /foo/bar/KT/633-ROYAL/633-ROYAL4.jpg
mv /foo/bar/KT/633-ROYAL/5.jpg /foo/bar/KT/633-ROYAL/633-ROYAL5.jpg
mv /foo/bar/KT/633-ROYAL/6.jpg /foo/bar/KT/633-ROYAL/633-ROYAL6.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/1.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI1.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/2.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI2.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/3.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI3.jpg
3
heemayl

renameでこれを行うことができます:

rename -n 's/(.*)\//$1\/$1/' */*

このコマンドは、処理するディレクトリのすぐ上のディレクトリで開始する必要があります。名前の変更を実行するために-nなしで実行した結果に満足している場合、最初に確認する変更のみをリストします。

実行例

$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
    ├── 1.jpg
    ├── 2.jpg
    └── 3.jpg
$ rename 's/(.*)\//$1\/$1/' */*
$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
    ├── SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
    ├── SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
    └── SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg

説明

rename 's/(.*)\//$1\/$1/' */*
  • s/a/b/substitute a by b
  • (.*)\/ –最後のスラッシュがグループ1として保存するまで(除外する)まですべてを取得しますおよび置換
  • $1\/$1 –グループ1(ディレクトリ名)、スラッシュ、グループ1(ファイル名プレフィックス)
1
dessert

以下は、編集したいディレクトリからそれを行う方法の小さな例です。

$> ls                                                                          
file1.txt  file2.txt  file3.txt
$> pwd
/home/xieerqi/testing_dir
$> find . -type f -printf "%f\0" | \                                           
> while IFS="" read -d "" filename ; do \                                      
> echo $filename ${PWD##*/}_$filename   ; done
file2.txt testing_dir_file2.txt
file1.txt testing_dir_file1.txt
file3.txt testing_dir_file3.txt

echomvまたはcpに置き換えます。必要に応じてコピーまたは移動します

1

名前を変更する必要があるファイルが存在するフォルダーで実行される、さらに別のbashのみのアプローチ:

for f in * ; do mv "$f" "$(basename "$(pwd)")"_"$f" ; done

これは、スペースを含むファイル名とフォルダー名も処理します。

0
vanadium

変更したいファイル名が置かれているフォルダーから実行するBashソリューション。 workdirをパスに変更する必要があります

#!/bin/bash

shopt -s globstar

workdir="/path/to/your/dir"

for folder in $workdir/**/*;do
  if [[ -d "$folder" ]]; then
    for file in "$folder"/*;do
        if [[ -f "$file" ]]; then
            fi="`basename "$file"`"
            fo="`basename "$folder"`"
            mv "$file" "$folder/$fo$fi"
        fi
    done
  fi
done

すべてのファイル in すべてのディレクトリがworkdirから再帰的に変更されます。

0
EdiD