web-dev-qa-db-ja.com

ファイル名の先頭からドットとスペースを削除する方法

先頭にドットとスペースがあり、末尾の前にドットが欠落している名前のjpgファイルを変更しようとしています(このような. StartjpgからStart.jpg

ドットはファイルをsedから非表示にし、ls -alはそれらのファイルをリストするため、ls -alsedにパイプしています。オンラインで多くのマニュアルを読みましたが、常にこのエラーが発生します

sed: -e expression #1, char 6: unknown command: `/'

私はもう試した

ls -al | sed -r '/^\./*.*/g'
ls -al | sed -r '/^\.//g'
ls -al | sed -r '/.*/[\.]g'
ls -al | sed 's/^\./\\1*./g'

そして、もっともっと、もっともっともっと。

また、filejpgをfile.jpgに変更する必要があります

8
user251046

Perl renameツール(DebianおよびUbuntuを含む友人ではrenameと呼ばれますが、他の場所ではprenameになる場合があります):

rename -n 's/(?<!\.)jpg$/.jpg/' *  # -n makes it show you what it'll do,
                                   # but not actually do it. Remove the -n to
                                   # actually rename

そのパターンを分解するには:jpg$は「「jpg」で終わる」という意味です。 (?<!\.)は、「そのjpgの前にドットがない」ことを意味します。これにより、foo.jpgfoo..jpgに変更できなくなります。

*は通常のシェルワイルドカードです。 renameは、名前の変更を検討するファイルのリストを取得します。もちろん、/path/to/dir/*を実行したり、ファイル名のリストを渡したり、findと組み合わせて使用​​したりできます。

最初からドットとスペースを削除することも非常に簡単です。

rename -n 's/^[. ]+//' *          # trying -n first is good practice

これにより、最初のすべてのドットとスペースが削除されます。 . . . foofooに変換します。

通常、*シェル展開では、ドットで始まる名前のファイル(隠しファイル)は生成されません。 1つのオプションは、.*を使用することです。また、2つの特別なエントリ.(現在のディレクトリ)と..(親ディレクトリ)も生成されます。この場合、それは無害でなければなりません。最初のコマンドはそれらを無視します(末尾がjpgではありません)。 2番目のコマンドはそれらの名前を変更しようとしますが、それはエラーを生成するだけです。別の方法は次のとおりです。

find -type f -exec rename -n 's/^[. ]+//' '{}' +

-type fはファイルのみに制限されます。もちろん、findの他のオプションも使用できます。

9
derobert

sedは非常に便利で用途の広いツールですが、適切に使用していません。これは、テキストファイル内の文字列の照合と置換に最適です。ファイルシステム上のファイルの名前を直接変更することはできません。

このタスクは、bashワンライナー(シェルであると想定)に適しています。 _. filejpg_などの名前を_file.jpg_に変更するには、次のようにします。

_find . -name '. *' -print0 | while read -d $'\0' file; do short_file=${file%jpg}.jpg; mv "$file" "${short_file:4}"; done
_

説明

findは、特定のファイルプロパティ(この場合はファイル名)に一致するファイルへのパスを返すプログラムです。現在のパスのサブディレクトリにある.jpgファイルだけを知りたい場合は、_find . -name "*.jpg"_を実行します。通常、これは各ファイルを新しい行に出力します。 _-print0_を使用すると、代わりに一致がnull文字で区切られます。これにより、出力を次のコマンドに渡すときに、スペースを含むファイル名を適切に処理できます。

_|_文字はパイプと呼ばれます。シェルに、左側のコマンドの出力を受け取り、右側のコマンドへの入力として渡すように指示します。この場合は、readループ内のwhileコマンドです。

readコマンドは、findの出力を取得して変数fileに割り当てるために使用されます。通常、これは一度に各Wordに値をfileに割り当てますが、_-d $'\0'$_を指定すると、割り当てはnull文字で区切られます(findのファイルを区切る方法と一致します) _-print0_フラグを使用)。

Whileループにより、readは、一致するファイル名ごとに「file」に繰り返し値を割り当てます。 doおよびdoneは、whileループの標準bash構文の一部です。

_while <something is true>; do
    <run some commands>
done
_

この場合、「コマンドを実行」は最初にファイル名の拡張子を修正し、それを新しい変数に割り当てます:_short_file=${file%jpg}.jpg_ __. filejpg_を_. file.jpg_に変更します。次に、mvを実行してファイルの名前を変更し、拡張子が修正されたファイル名の先頭の_._を削除します:_mv "$file" ${short_file:2}_。

4
drs

他の回答の代わりに、グラフィカルツール GPRename を使用できます。文字の置き換え、ファイル名の切り捨てなどを行うことができます。利点は、名前を変更する前に新しいファイル名を確認する組み込みのプレビュー機能があることです。ただし、一度に1つのディレクトリで機能するため、サブフォルダ内の多数のフォルダで使用するのは不便です。ただし、10個未満のフォルダーの場合は問題ありません。

0
A.L