私はフォルダの名前を変更しようとして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
これを行う方法はありますか?
どうもありがとう!
リスト内の名前にスペースが含まれていないと仮定する、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)
rename.py
として保存します。コマンドで(ターミナルで)実行します:
python /path/to/rename.py
スクリプト:
os.walk()
を使用して、ディレクトリを下から上へ再帰的に調べます。xargs
でmv
を使用できます:
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 ?...
a.txt
ファイルには1行に1つのエントリがあるため、リストされている名前には\n
(改行)文字が含まれていませんよね?
行にはspace charで区切られた2つの名前が含まれているため、名前にspace charが含まれていませんか? (または、リストされた名前に固定長を使用することもできます)。
名前に\n
もspace
文字も含まれていない場合は、これを試してください。
awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv
awk
は、a.txt
ファイルから読み取られた行の名前の順序を逆にするために使用されます。 \0
は、標準出力に出力されるときに名前を区切るために使用されます。
xargs
は標準入力を読み取ります。
-0
:\0
は、標準入力から読み取られた要素の区切り文字として使用されます-L 2 mv
:mv
コマンドは、一度に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つの「単語」、つまりターゲットディレクトリと新しい名前があり、どちらにも空白を含めることはできません。
while read -r from to; do mv "$from" "$to"; done < file
file
の各行を読み取り、最初の文字列(最初の空白まで)を$from
に割り当て、残りの行を$to
に割り当ててから、それぞれでmv
を実行しますそれら。