質問
一連のパッケージの名前を変更してバージョン番号を削除するにはどうすればよいですか? expr
と %%
の両方をいじってみましたが、何の役にも立ちません。
例:
Xft2-2.1.13.pkg
は Xft2.pkg
jasper-1.900.1.pkg
は jasper.pkg
xorg-libXrandr-1.2.3.pkg
は xorg-libXrandr.pkg
解決
bashのパラメーター拡張機能を使用できます
for i in ./*.pkg ; do mv "$i" "${i/-[0-9.]*.pkg/.pkg}" ; done
スペースを含むファイル名には引用符が必要です。
他のヒント
すべてのファイルが同じディレクトリにある場合、シーケンス
ls |
sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' |
sh
あなたの仕事をします。 sed コマンドは一連の mv コマンドを作成し、シェルにパイプすることができます。最初に末尾の |なしでパイプラインを実行するのが最善ですsh
を使用して、コマンドが目的どおりに動作することを確認します。
複数のディレクトリを再帰するには、次のようなものを使用します
find . -type f |
sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' |
sh
sed の正規表現グループ化シーケンスは、単一の括弧ではなく、円記号 \(
および \)
が前に付いた括弧です。 (
および)
。
次のようなことをします:
for file in *.pkg ; do
mv $file $(echo $file | rev | cut -f2- -d- | rev).pkg
done
すべてのファイルが現在のディレクトリにあると仮定します。そうでない場合は、上記のJavierのアドバイスに従ってfindを使用してみてください。
編集:また、このバージョンでは、他の上記のようなbash固有の機能を使用しないため、移植性が向上します。
現在受け入れられている回答とほぼ同等のPOSIXです。これは、Bash専用の $ {variable / substring / replacement}
パラメーター展開を、Bourne互換シェルで使用可能なパラメーターと交換します。
for i in ./*.pkg; do
mv "$i" "${i%-[0-9.]*.pkg}.pkg"
done
パラメータ拡張 $ {variable%pattern}
は、 pattern
に一致するサフィックスを削除した variable
の値を生成します。 (プレフィックスを削除するための $ {variable#pattern}
もあります。)
サブパターン-[0-9。] *
は、おそらく誤解を招くかもしれませんが、受け入れられた回答から除外しました。これは正規表現ではなく、globパターンです。したがって、「ダッシュの後にゼロ個以上の数字またはドットが続く」という意味ではありません。代わりに、「ダッシュ、それに続く数字またはドット、その後に続くもの」を意味します。 「何でも」は、最短ではなく最短の一致になります。 (Bashは、最短ではなく最長のプレフィックスまたはサフィックスをトリミングするために、 ##
および %%
を提供しています。)
このためには、 sed
を使用することをお勧めします。
find . -type f -name "*.pkg" |
sed -e 's/((.*)-[0-9.]*\.pkg)/\1 \2.pkg/g' |
while read nameA nameB; do
mv $nameA $nameB;
done
正規表現の構成は演習として残されます(スペースを含むファイル名を扱う場合と同様)
任意の* nixで sed
が利用可能であると想定できますが、確実ではありません
sed -n
をサポートして、mvコマンドを生成します。 (注: GNU sed
のみがこれを行います。)
それでも、bashビルトインとsedで、これを行うためのシェル関数をすばやく作成できます。
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
mv -v "$file" "$(sed $sed_pattern <<< $file)"
done
else
echo "usage: sedrename 's|\(.*\)\(-[0-9.]*\.pkg\)|\1\2|' *.pkg
before:
./Xft2-2.1.13.pkg
./jasper-1.900.1.pkg
./xorg-libXrandr-1.2.3.pkg
after:
./Xft2.pkg
./jasper.pkg
./xorg-libXrandr.pkg
sed_pattern files..."
fi
}
使用法
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
ターゲットフォルダーの作成:
mv
は使用できないターゲットフォルダーを自動的に作成しないため
sedrename
の初期バージョン。
これは非常に小さな変更なので、その機能を含めると便利です。
bash以降、ユーティリティ関数 abspath
(または絶対パス)が必要になります
このビルドは組み込まれていません。
# generate the rename target
target="$(sed $sed_pattern <<< $file)"
# Use absolute path of the rename target to make target folder structure
mkdir -p "$(dirname $(abspath $target))"
# finally move the file to the target name/folders
mv -v "$file" "$target"
一度、ターゲットフォルダーを生成できます 新しいフォルダー構造を含むsed / renameパターン。
これにより、ターゲットフォルダの名前が確実にわかります。私たちが ターゲットファイル名で使用する必要がある名前を変更します。
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
target="$(sed $sed_pattern <<< $file)"
mkdir -p "$(dirname $(abspath $target))"
mv -v "$file" "$target"
done
else
echo "usage: sedrename 's|Beethoven - |Beethoven/|g' *.mp3
before:
./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3
after:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
sed_pattern files..."
fi
}
完全なフォルダ対応スクリプトは次のとおりです...
sedrename 's|.*/||' **/*.mp3
before:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
after:
./Beethoven/ # (now empty)
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3
もちろん、特定のターゲットフォルダがない場合でも機能します
すべての曲をフォルダーに入れたい場合は、 ./ Beethoven /
これを行うことができます:
使用法
<*>ボーナスラウンド...
このスクリプトを使用して、ファイルをフォルダーから単一のフォルダーに移動します。
一致するすべてのファイルを収集して配置したいと仮定した場合 現在のフォルダで、それを行うことができます:
<*>sed正規表現パターンに関する注意
このスクリプトでは通常のsedパターンルールが適用されますが、これらのパターンは
PCRE(Perl互換の正規表現)。 sed
sed -r
または sed -E
を使用した拡張正規表現構文
プラットフォームによって異なります。
の詳細な説明については、POSIX準拠の man re_format
を参照してください
sedの基本および拡張正規表現パターン。
名前の変更は、この種のものに使用するはるかに簡単なツールであることがわかりました。 OSX用Homebrewで見つけました
あなたの例では:
rename 's/\d*?\.\d*?\.\d*?//' *.pkg
「s」は代替を意味します。フォームはs / searchPattern / replacement / files_to_applyです。これには正規表現を使用する必要があり、少し勉強する必要がありますが、努力するだけの価値はあります。
これは次のことを前提として機能しているようです
- すべてが$ pkgで終わる
- バージョン番号は常に&quot;-&quot;で始まります
.pkgを取り除き、次に-..を取り除きます。
for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done
同じフォルダに複数の *。txt
ファイルを .sql
に名前変更しました。
以下は私のために働いた:
for i in \`ls *.txt | awk -F "." '{print $1}'\` ;do mv $i.txt $i.sql; done
この回答をありがとう。また、何らかの問題がありました。 .nzb.queuedファイルを.nzbファイルに移動します。ファイル名にスペースなどが含まれていたため、問題が解決しました。
find . -type f -name "*.nzb.queued" |
sed -ne "s/^\(\(.*\).nzb.queued\)$/mv -v \"\1\" \"\2.nzb\"/p" |
sh
これは、Diomidis Spinellisの回答に基づいています。
正規表現は、ファイル名全体に対して1つのグループを作成し、.nzb.queuedの前の部分に対して1つのグループを作成してから、シェル移動コマンドを作成します。文字列を引用符で囲みます。これにより、sedによって既に実行されているため、シェルスクリプトでループを作成することも回避されます。