ファイル名の先頭に同じ単語が含まれるように、何百ものファイル名をどのように変更できますか? [閉鎖]

ファイル名の先頭に同じ単語が含まれるように、何百ものファイル名をどのように変更できますか? [閉鎖]

以下は、名前を変更する必要があるファイルの小さなサンプルです。

    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つの問題は、これがksh93Bashと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

関連情報