私のUnixディレクトリには次のファイルがたくさんあります。
filename_1234567.txt
次のように、ファイル名の前に最後の3文字をコピーして各ファイル名を変更する必要があります。
567_filename_1234567.txt
注:拡張子とファイル名はどちらも可変です。
私はSolarisマシンで実行しています。
答え1
そしてzsh
:
autoload zmv
zmv -n '*(???).*' '$1_$f'
満足のいくものを削除してください-n
。
答え2
ファイル名の前に下線が付いたファイルのデフォルト名の最後の3文字を追加しますか?
#!/bin/bash
EXT=.txt
for file in *${EXT}; do # presuming all the filenames have no spaces
base=${file%${EXT}}
prefix=${base:(-3)}
newname=${prefix}_${base}${EXT}
mv ${file} ${newname}
done
Kornシェルでは、使用するトリックが具体的であるbash
ため機能しません。
ksh[3]: prefix=${base:(-3)}: bad substitution
答え3
私は次のことが好きです:
#!/bin/sh
for i in filename_*.txt; do echo "$i"; done |
sed "s/filename_\([0-9]*\)\([0-9]\{3\}\)\.txt/mv -i 'filename_\1\2.txt' '\2_filename_\1\2.txt'/g"
mv
これにより、ジョブを完了したコマンドのリストが印刷されます。正しいコマンドが出力されたら、| sh
sedコマンドの最後に追加して、シェルにそのコマンドを実行させます。
スクリプトはsed
submit コマンドs
と逆参照機能を使用して、正規表現に一致する文字列部分を置き換えます。
s/regex/replacement/
\(
内部と間の正規表現パターン部分は、代替\)
文字列で引用できます。\N
ここで in は数値です。
答え4
純粋なawk
解決策:基本的なアイデアは、基本名の最後の3文字を抽出することです。これは部分文字列形式length - 6
(.txt
拡張子を考慮する必要があるため6文字)を意味しますlength - 3
。ここでは、最初に対応する部分文字列をVARとして抽出し、次にmv
実行する2つのファイル名を含むコマンド。最後に、system
関数にコマンドの実行を要求します。
パスワード:
awk 'BEGIN{
VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3));
CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]);
print CMD;
system(CMD);
close(CMD)
}' filename_1234567.txt
デモ:
$ awk 'BEGIN{VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3)); CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]); print CMD; system(CMD); close(CMD)}' filename_1234567.txt
mv filename_1234567.txt 567_filename_1234567.txt
$ ls filename_1234567.txt
ls: cannot access filename_1234567.txt: No such file or directory
$ ls 567_filename_1234567.txt
567_filename_1234567.txt
$