以下は、名前を変更する必要があるファイルの小さなサンプルです。
ID_EDMSCP_20160815.txt.pgp
ID_EDMSCP_20160816.txt.pgp
ID_EDMSCP_20160817.txt.pgp
ID_EDMSCP_20160818.txt.pgp
他の人の質問に基づいてスクリプトを作成しました。
for file in ID_EDMSCP_*.txt.pgp
do
mv -i "${file}" "${file/-ID-/-SUBMIT_GO_ID-}"
done
ただし、次のメッセージが表示されます。
mv: `ID_EDMSCP_20160815.txt.pgp' and `ID_EDMSCP_20160815.txt.pgp' are the same file
そして何も名前が変わりませんでした。私は何を逃したことがありませんか?
答え1
mv -i "${file}" "${file/-ID-/-SUBMIT_GO_ID-}"
-ID-
この文字列置換は、ソースファイル名に表示されない置換を示します。私の考えでは、あなたはこのように言いたいと思います。
mv -i "${file}" "${file/ID_/SUBMIT_GO_ID_}"
もう1つの問題は、これがksh93
BashとZshでも使用できる機能です。純粋なPOSIXシェルではありません。#!/bin/sh
スクリプトの上部で使用すると、POSIXシェルまたはPOSIX以前のBourneシェルインタプリタで実行されます。一部のシステムでは、これはわかりません。
高度なシェルの非標準機能にアクセスできない場合は、さまざまな選択肢があります。
sed
このスクリプトをすべてのUnixタイプのシステムに移植する必要がある場合は、sed
代替スクリプトに切り替えることができます。
mv -i "$file" "$(echo $file | sed -e 's/^ID_/SUBMIT_GO_ID_/')"
スタイルコマンド補間を使用するため、少なくとも$()
POSIXシェルが必要ですが、どこでも高レベルのシェルを期待するよりも「考える」方が簡単です。
スクリプトをすべてのBourneタイプシェルで実行する必要がある場合は、バックティックスタイルのコマンド補間に切り替えることができます。ファイル名にスペースが含まれていると正しく実行するのは難しいかもしれませんが、公開した例によると次のようになります。そうではありません。したがって、あなたの目的に応じて、これは以前のオプションと同じでなければなりません。
mv -i "$file" `echo $file | sed -e s/^ID_/SUBMIT_GO_ID_/`
ミリメートル波
もう一つのオプションはインストールすることですmmv
、このプログラムは私が知っているUnix型システムにはインストールされていませんが、通常は標準のパッケージリポジトリにパッケージされています。を使用すると、mmv
シェルスクリプトループ全体を次のように置き換えることができます。
$ mmv 'ID_*' 'SUBMIT_GO_ID_#1'
すべての名前変更要求はサポートされていないため、-i
フラグはありません。mmv
しかし、計画されたすべての名前の変更を事前に確認し、作業を開始する前に問題を検出しようとするので、おそらくあなたの目的に十分近いでしょう。
名前を変更する
別のオプションは、rename
少なくとも3つのバリエーションで存在するコマンドです。持つ二つ フォーク同じ名前のLarry WallのPerlスクリプト。そのうちの1つは、Perlディストリビューションの一部としてシステムにすでにインストールされている可能性があります。以来util-linux
バリアントは通常、このバージョンではなくLinuxシステムにインストールされるか、またはその隣にインストールされます。両方がインストールされている場合は、prename
競合を避けるためにPerlベースのバージョンを呼び出すことができます。
Perlベースの主な利点は、次のものを使用できることです。パール正規表現mmv
これは、サポートされているglob式またはサポートされているPOSIX正規表現よりも強力ですsed
。ただし、この特定の例では操作が簡単であるため重要ではありません。
$ rename '^ID_' SUBMIT_GO_ID_ ID_EDMSCP_*.txt.pgp
このutil-linux
バージョンでは、最初の引数を「式」と呼びますが、POSIX正規表現やPerl正規表現ではないため、はるかに弱いです。これはグローバル式ではなく、リテラル文字列にすぎません。しかし、上記のように、この特別なケースでは、この制限は実際に私たちを妨げません。
$ rename ID_ SUBMIT_GO_ID_ ID_EDMSCP_*.txt.pgp
mmv
同様に、rename
この-i
フラグはサポートされていません。
普通の古いベルンシェル
要約すると、入力パターンが出力パターンの末尾に表示されるため、特定のケースではより簡単な解決策が可能になり、移植可能なBourneシェル構文を使用してすべての操作を実行できます。
for file in ID_EDMSCP_*.txt.pgp
do
mv -i "$file" SUBMIT_GO_"$file"
done
シェル言語の内部メカニズムは必ずしも十分ではないので、しばしば必要な複雑な選択肢を上に残しました。
答え2
この試み:
for file in ID_EDMSCP_*.txt.pgp
do
mv -i "${file}" SUBMIT_GO_"${file}"
done
答え3
Linuxでは、次のものを使用できます。rename
注文する。非常に制限的ですが、この簡単なユースケースには十分です。最初の部分文字列を別の文字列に置き換えます。
rename ID SUBMIT_GO_ID ID_EDMSCP_*.txt.pgp
Debianおよびその派生製品(Ubuntu、Mintなど)では、コマンドが呼び出されますrename.ul
。これらのディストリビューションのコマンドは、互換性のrename
ない構文を使用する別のコマンドです。prename
。このコマンドを使用すると、次のことができます。
prename 's/ID/SUBMIT_GO_ID/' ID_EDMSCP_*.txt.pgp