フォルダには何千ものテキストファイルがあり、特定の方法で名前が付けられます。
たとえば、
Image_234_Data_7778_n0.txt
Image_234_Data_7778_n1.txt
Image_234_Data_7778_n2.txt
Image_954_Data_4478_n0.txt
Image_954_Data_4478_n1.txt
Image_954_Data_4478_n2.txt
Image_104_Data_9878_n0.txt
Image_104_Data_9878_n1.txt
Image_104_Data_9878_n2.txt
など...
内容が次のようなソースファイル(ファイル名を変更して「何が何であるか」を追跡するために使用されます)を作成したいと思います。
1_1.txt:Image_234_Data_7778_n0.txt
1_2.txt:Image_234_Data_7778_n1.txt
1_3.txt:Image_234_Data_7778_n2.txt
2_1.txt:Image_954_Data_4478_n0.txt
2_2.txt:Image_954_Data_4478_n1.txt
2_3.txt:Image_954_Data_4478_n2.txt
3_1.txt:Image_104_Data_9878_n0.txt
3_2.txt:Image_104_Data_9878_n1.txt
3_3.txt:Image_104_Data_9878_n2.txt
など...
誰もが私のためにこれを行うコードを書くのに役立ちますか?
答え1
私はあなたのファイル名が数字で終わらず、一連の数字であるランダムなテキストXXXXNNN.txt
形式であり、同じXXXにグループ化したいとします。XXXX
NNN
戦略:アルファベット順にファイルを繰り返し、XXXXセクションが変更された時期を検出します。各グループに新しい名前を生成します。 1つのマイナーな問題は、NNN部分が可変幅の場合、アルファベット順にソートされないことです。 NNN=10 は NNN=1 と NNN=2 の間に表示されます。
current=
numbers=
i=0
for x in *.txt ''; do
stem=${x%.*}
n=${stem##*[!0-9]}
stem=${stem%$n}
if [ "$stem" != "$current" ]; then
for k in $(printf '%s\n' $numbers | sort -n); do
y=${i}_${k}.txt
echo mv "$current$k.txt" "$y"
done
current=$stem
numbers=$n
i=$((i+1))
else
numbers="$numbers $n"
fi
done
ファイル名の変更、ファイルへの情報の書き込みecho mv
など、使用したいコマンドに置き換えます。mv
echo …
ファイル名を変更して以前の名前を追跡する代わりに、次のものを使用することをお勧めします。シンボリックリンク元の名前と単純化された名前を使用してファイルにアクセスできます。
答え2
次のファイルを含むテストディレクトリを作成した後:
Image_104_Data_9878_n0.txt, Image_104_Data_9878_n1.txt,
Image_234_Data_7778_n0.txt, Image_234_Data_7778_n1.txt,
Image_234_Data_7778_n2.txt, Image_954_Data_4478_n0.txt,
Image_954_Data_4478_n1.txt, Image_954_Data_4478_n2.txt
それから私は次のことをしました。
printf %s\\n * | sort --debug -t_ -k2,2n -k5.2n,5.2n
結果:
Image_104_Data_9878_n0.txt
___
_
__________________________
Image_104_Data_9878_n1.txt
___
_
__________________________
Image_234_Data_7778_n0.txt
___
_
__________________________
Image_234_Data_7778_n1.txt
___
_
__________________________
Image_234_Data_7778_n2.txt
___
_
__________________________
Image_954_Data_4478_n0.txt
___
_
__________________________
Image_954_Data_4478_n1.txt
___
_
__________________________
Image_954_Data_4478_n2.txt
___
_
__________________________
sort
たとえば、2cdで区切られたフィールドでは、フィールドの先頭からフィールドの終わりまでの数字に基づいて主にソートし、5番目のフィールドの2番目の2cdバイトに基づいて数字に基づいてソートするように指示されました。私はそれが正確に何をしているのかを知らせるために出力を要求しました。_
-k2,2n
-k5.2,5.2n
--debug
主にフィールド4、主にフィールド2、2番目はフィールド5.2、最も重要ではないものは2番目のフィールドに簡単に配置できます。あなたの例で提供されている順序の韻や理由を特定できないので、これを言うことです。あなたはこれを次のように割り当てたと仮定することができます。
- 1_1:234/7778
- 2_1:954/4478
- 3_1:104/9878
...これまでの並べ替えのための適切なコマンドを作成していないので、これを行う方法についてのアドバイスが必要な場合があります。この仮定に基づいて、私は次のようにします。
printf %s\\n * |
sort -t_ -k4,4n -k5.2n,5.2n |
nl -bp'_n0\.' -s_ |
sed 's/\(I[^.]*_n\)\(.*\)/\2:\1\2/;N
s/ *\([0-9]*_\)\(.*\n\) *\([^_]*I\)/\1\2\1\3/;P;D'
私はこれがあなたが探しているものと非常に近い結果を生み出すと思います。願いより?
1_0.txt:Image_954_Data_4478_n0.txt
1_1.txt:Image_954_Data_4478_n1.txt
1_2.txt:Image_954_Data_4478_n2.txt
2_0.txt:Image_234_Data_7778_n0.txt
2_1.txt:Image_234_Data_7778_n1.txt
2_2.txt:Image_234_Data_7778_n2.txt
3_0.txt:Image_104_Data_9878_n0.txt
3_1.txt:Image_104_Data_9878_n1.txt
私が指定したので、4番目のフィールドに基づいてソートされ、番号が付けられますが、-k4,4n
指示に従うのはsort
簡単です。-k2,2n
nl
このコマンドは、文字列を含む行にのみ番号を付けるように要求することで機能します_n0.
。sed
次のように出力を受け取ります。
1_Image_954_Data_4478_n0.txt
Image_954_Data_4478_n1.txt
Image_954_Data_4478_n2.txt
2_Image_234_Data_7778_n0.txt
Image_234_Data_7778_n1.txt
Image_234_Data_7778_n2.txt
3_Image_104_Data_9878_n0.txt
Image_104_Data_9878_n1.txt
...最初に_n[0-9]*.txt
ビットを行の先頭にコピーし、N
extは次の行を取得します。パターンスペースが次の場合:
*num_.*\n [^_]*I
... この時点で、1 行目の数値ビットを 2 行目に追加します。このコマンドで生成されたテキストファイルから移動操作に移動するには、次のようにします。
sed 's/\([^:]*\):\(.*\)/$* \2 \1/' <txtfile |
sh -s -- echo mv
出力
mv Image_954_Data_4478_n0.txt 1_0.txt
mv Image_954_Data_4478_n1.txt 1_1.txt
mv Image_954_Data_4478_n2.txt 1_2.txt
mv Image_234_Data_7778_n0.txt 2_0.txt
mv Image_234_Data_7778_n1.txt 2_1.txt
mv Image_234_Data_7778_n2.txt 2_2.txt
mv Image_104_Data_9878_n0.txt 3_0.txt
mv Image_104_Data_9878_n1.txt 3_1.txt
シェルプロセスの最初の引数なので、ちょうどedとマークされていますが、先ほど行ったようにecho
それを削除して実行すると、同じ結果が得られます。
ls -m
1_0.txt, 1_1.txt, 1_2.txt, 2_0.txt, 2_1.txt, 2_2.txt, 3_0.txt, 3_1.txt
Gillesは良いアイデアだと思うリンクをお勧めしますが、個人的にはソフトリンクを避け、可能であればミラーリングされたハードリンクディレクトリを作成します。ほぼ同じ方法でこれを実行できますが、代わりに使用することをお勧めしln
ますmv
。
答え3
このような問題を解決する1つの方法(特にスクリプトに精通していない場合)は、スプレッドシートを使用してスクリプトを生成することです。再利用可能なスクリプトを作成する場合は、これは良い方法ではありませんが、他の方法でスクリプトを作成する方法を学ぶ時間がない人のためのワンタイムタスクに役立ちます。
達成したい名前の変更(または接続)は、aの前のすべてをaの_n
前の単一のシーケンス番号に変更_
し、残りは_n
変更されていないままにするようです。正確な意図ではない場合は、スプレッドシートの式を簡単に修正できます。
たとえば、(水平スクロールの必要性を減らすためにファイル名を減らします):
A2 B2 C2 D2 E2
i234d7778_n0.txt =FIND("_n",A2) =LEFT(A2,B2) =D1+(C2<>C1) =D2&"_"&RIGHT(A2,LEN(A2)-B2-1)
i234d7778_n0.txt 10 i234d7778_ 1 1_0.txt
行1ではなく行2から始まる理由は、D2の比較が行1に進むからである。 (代替案は最初の行に配置することですが、特別な場合はD1は行1に配置されます。)
D2の式は簡単に言うと次のようになります。=IF(C2=C1,D1,D1+1)
スプレッドシートと同様に、ファイルのリストを列Aに貼り付け、ファイルの数に応じて列Bから列Eまで繰り返します。名前変更を実行するスクリプトを生成するには、「F」または「G」列を追加します。
F2 G2
="mv "&A2&" "&E2 ="ln "&A2&" new-name-directory/"&E2
mv i234d7778_n0.tx 1_0.txt ln i234d7778_n0.tx new-name-directory/1_0.txt
列と列Gは、実行可能なスクリプトのテキストを提供します。