web-dev-qa-db-ja.com

.txtファイルを使用してフォルダーの名前を変更する

私はフォルダの名前を変更しようとしてbashを使用して端末で作業しています:

1
2
3
4
5

A.txtファイルに従って名前を変更したい:

a 2
c 3
d 5
e 1
b 4

.txtファイル内の順序は完全にランダムです。フォルダの名前を変更して、次のようにする方法を見つけたいと思っています。

1 > e
2 > a
3 > c
4 > b
5 > d

これを行う方法はありますか?

どうもありがとう!

7
Ditte

リスト内の名前にスペースが含まれていないと仮定するbetween名前、以下のスクリプトはテキストファイルからフォルダーの名前を変更します再帰的に。ファイルの行を読み取り、それらを2つ(新しい名前、古い名前)に分割し、second文字列で名前が付けられた発生フォルダーの名前を変更します行をfirst文字列に入れます。

前述のように再帰的に、ディレクトリツリーの下から上にこれを行います。これにより、スクリプトの問題が回避され、既に名前が変更されている可能性のある親フォルダーのフォルダー名を変更しようとします。

#!/usr/bin/env python
import os
import shutil

# -- set the (absolute) path to the targeted folder below
dr = "/home/jacob/Bureaublad/testfolder"
# -- set the path to the textfiles below
ren = "/home/jacob/Bureaublad/testfolder/renfile.txt"

renlist = [cpl for cpl in [l.split() for l in open(ren).readlines()] if cpl]
currnames = [r[1] for r in renlist]

for root, dirs, files in os.walk(dr, topdown = False):
    for dr in dirs:
        try:
            # look up the name, pass if not in the list
            i = currnames.index(dr)
        except ValueError:
            pass
        else:
            newname = renlist[i][0]
            shutil.move(root+"/"+dr, root+"/"+newname)

使い方

  1. スクリプトを空のファイルにコピーし(プレーンテキストエディターで)、rename.pyとして保存します。
  2. スクリプトのheadセクションで、テキストファイルとディレクトリへの実際のパスを設定します
  3. コマンドで(ターミナルで)実行します:

    python /path/to/rename.py
    

説明

スクリプト:

  • 名前のリストを作成します-couples:newname/oldname
  • pythonのos.walk()を使用して、ディレクトリを下から上へ再帰的に調べます。
  • フォルダーの名前が名前カップルの2番目の項目と一致する場合、フォルダーの名前を最初の名前に変更します。
  • フォルダの名前がリストされていない場合は、変更されません。
4
Jacob Vlijm

xargsmvを使用できます:

xargs -r -a /path/to/file.txt -L1 mv

(ファイルがあるディレクトリにいると仮定します)。

xargsは、入力をコマンドの引数に変換します。

  • -a fooからfooから入力を読み取ります。
  • -L1は、コマンド呼び出しごとに正確に1行の入力を使用します。
  • -rは、行が空の場合にコマンドを実行しないようにします

たとえば、mvの代わりにecho mvを使用して、実行中のコマンドを表示します。

$ xargs -r -a foo.txt -L1 echo mv
mv a 2
mv c 3
mv d 5
mv e 1
mv b 4

-pオプションを使用して、コマンドを実行する前にxargsを確認することもできます。

$ xargs -r -p -a foo.txt -L1 mv
mv a 2 ?...n
mv c 3 ?...n
mv d 5 ?...y
mv e 1 ?...mv: cannot stat ‘d’: No such file or directory
n
mv b 4 ?...
6
muru

a.txtファイルには1行に1つのエントリがあるため、リストされている名前には\n(改行)文字が含まれていませんよね?

行にはspace charで区切られた2つの名前が含まれているため、名前にspace charが含まれていませんか? (または、リストされた名前に固定長を使用することもできます)。

名前に\nspace文字も含まれていない場合は、これを試してください。

awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv

awkは、a.txtファイルから読み取られた行の名前の順序を逆にするために使用されます。 \0は、標準出力に出力されるときに名前を区切るために使用されます。

xargsは標準入力を読み取ります。

  • -0\0は、標準入力から読み取られた要素の区切り文字として使用されます
  • -L 2 mvmvコマンドは、一度に2つのパラメーターで呼び出されます。

テスト:

$ ls -al
total 40
drwxrwxr-x  7 stacko stacko  4096 May 31 11:25 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 1
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 2
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 3
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 4
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 5
-rw-rw-r--  1 stacko stacko    20 May 31 11:24 a.txt
$ cat a.txt
a 2
c 3
d 5
e 1
b 4
$ awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv -v
'2' -> 'a'
'3' -> 'c'
'5' -> 'd'
'1' -> 'e'
'4' -> 'b'
$ ls -al
total 40
drwxrwxr-x  7 stacko stacko  4096 May 31 11:26 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 a
-rw-rw-r--  1 stacko stacko    20 May 31 11:24 a.txt
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 b
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 c
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 d
drwxrwxr-x  2 stacko stacko  4096 May 31 11:25 e
2
Jay jargot

上記の簡単な例では、各行に2つの「単語」、つまりターゲットディレクトリと新しい名前があり、どちらにも空白を含めることはできません。

while read -r from to; do mv "$from" "$to"; done < file 

fileの各行を読み取り、最初の文字列(最初の空白まで)を$fromに割り当て、残りの行を$toに割り当ててから、それぞれでmvを実行しますそれら。

2
terdon