web-dev-qa-db-ja.com

sedを使用してファイルの名前を一括変更する

目的

これらのファイル名を変更します。

  • F00001-0708-RG-biasliuyda
  • F00001-0708-CS-akgdlaul
  • F00001-0708-VF-hioulgigl

これらのファイル名に:

  • F0001-0708-RG-biasliuyda
  • F0001-0708-CS-akgdlaul
  • F0001-0708-VF-hioulgigl

シェルコード

テストする:

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/'

実行するには:

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/' | sh

私の質問

Sedコードがわかりません。置換コマンドとは

$ sed 's/something/mv'

手段。そして、私は正規表現をいくらか理解しています。しかし、私はここで何が起こっているのか理解できません:

\(.\).\(.*\)

またはここ:

& \1\2/

前者は、「単一の文字、単一の文字、単一の文字の任意の長さのシーケンス」という意味のように見えますが、確かにそれ以上のものがあります。後半に関しては:

& \1\2/

何も思いつきません。このコードを本当に理解したいです。ここで私を助けてください、みんな。

73

まず、これを行う最も簡単な方法は、prenameコマンドまたはrenameコマンドを使用することです。

Ubuntu、OSX(Homebrewパッケージrename、MacPortsパッケージ_p5-file-rename_)、またはPerlの名前が変更された他のシステム(プリネーム):

_rename s/0000/000/ F0000*
_

または、RHELなどのutil-linux-ngから名前を変更するシステムの場合:

_rename 0000 000 F0000*
_

これは、同等のsedコマンドよりもはるかに理解しやすいものです。

ただし、sedコマンドの理解に関しては、sedマンページが役立ちます。 man sedを実行して&を検索(/コマンドを使用して検索)すると、s/foo/bar/replacementsの特殊文字であることがわかります。

_  s/regexp/replacement/
         Attempt  to match regexp against the pattern space.  If success‐
         ful,  replace  that  portion  matched  with  replacement.    The
         replacement may contain the special character & to refer to that
         portion of the pattern space  which  matched,  and  the  special
         escapes  \1  through  \9  to refer to the corresponding matching
         sub-expressions in the regexp.
_

したがって、\(.\)は最初の文字と一致し、_\1_で参照できます。次に、_._は次の文字と一致します。これは常に0です。その後、\(.*\)はファイル名の残りの部分と一致し、_\2_で参照できます。

置換文字列は、_&_(元のファイル名)と、2番目の文字を除くファイル名のすべての部分である_\1\2_を使用して、すべてをまとめます。

これは非常に不可解な方法です、私見。何らかの理由で名前変更コマンドが使用できず、sedを使用して名前変更を実行したい場合(または、名前変更のために複雑すぎる操作を行っていた場合)、正規表現をより明示的にすると読みやすくなります。おそらく次のようなもの:

_ls F00001-0708-*|sed 's/F0000\(.*\)/mv & F000\1/' | sh
_

S/search/replacement /で実際に何が変更されているかを確認できると、読みやすくなります。また、誤って2回実行した場合など、ファイル名から文字が吸い出されることはありません。

132
Edward Anderson

sedの説明がありました。シェルだけを使用でき、外部コマンドは不要です

for file in F0000*
do
    echo mv "$file" "${file/#F0000/F000}"
    # ${file/#F0000/F000} means replace the pattern that starts at beginning of string
done
39
ghostdog74

数年前にsedを使用したバッチの名前変更の例を含む小さな投稿を書きました。

http://www.guyrutenberg.com/2009/01/12/batch-renaming-using-sed/

例えば:

for i in *; do
  mv "$i" "`echo $i | sed "s/regex/replace_text/"`";
done

正規表現にグループ(例:\(subregex\)が含まれている場合、それらを置換テキストで\1\\2などとして使用できます。

17
Guy

最も簡単な方法は次のとおりです。

for i in F00001*; do mv "$i" "${i/F00001/F0001}"; done

または、移植性のある、

for i in F00001*; do mv "$i" "F0001${i#F00001}"; done

これにより、ファイル名の接頭辞F00001F0001に置き換えられます。ここにmaheshへのクレジット: http://www.debian-administration.org/articles/15

15
Mike

sedコマンド

s/\(.\).\(.*\)/mv & \1\2/

置き換えることを意味します:

\(.\).\(.*\)

で:

mv & \1\2

通常のsedコマンドと同じです。ただし、カッコ、&および\nマーカーは少し変更します。

検索文字列は、先頭の単一文字に一致し(パターン1として記憶)、その後に単一文字が続き、その後に文字列の残りが続きます(パターン2として記憶されます)。

置換文字列では、これらの一致したパターンを参照して、置換の一部として使用できます。一致した部分全体を&として参照することもできます。

したがって、そのsedコマンドが実行しているのは、元のファイル(ソース用)と文字1および3以降に基づいてmvコマンドを作成し、文字2(宛先用)を効果的に削除することです。次の形式に沿って一連の行が表示されます。

mv F00001-0708-RG-biasliuyda F0001-0708-RG-biasliuyda
mv abcdef acdef

等々。

6
paxdiablo

バックスラッシュとパレンの意味は、「パターンを一致させながら、ここで一致するものを保持する」ということです。後で、置換テキスト側で、「\ 1」(最初の括弧で囲まれたブロック)、「\ 2」(2番目のブロック)などで、それらの記憶されたフラグメントを取得できます。

2
Pointy

ここに私がやることがあります:

for file in *.[Jj][Pp][Gg] ;do 
    echo mv -vi \"$file\" `jhead $file|
                           grep Date|
                           cut -b 16-|
                           sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done

それで問題なければ、最後に| shを追加します。そう:

for file in *.[Jj][Pp][Gg] ;do 
    echo mv -vi \"$file\" `jhead $file|
                           grep Date|
                           cut -b 16-|
                           sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done | sh
0
Chris Po

かっこは、バックスラッシュ番号で使用する特定の文字列をキャプチャします。

0
Ewan Todd
 ls F00001-0708-*|sed 's|^F0000\(.*\)|mv & F000\1|' | bash
0
ghostdog74

あなたが本当にしているのが、2番目の文字を削除することである場合、それが何であるかに関係なく、あなたはこれを行うことができます:

s/.//2

ただし、コマンドはmvコマンドを作成し、実行のためにシェルにパイプします。

これはあなたのバージョンよりも読みにくいです:

find -type f | sed -n 'h;s/.//4;x;s/^/mv /;G;s/\n/ /g;p' | sh

findが各ファイル名の先頭に「./」を付けているため、4番目の文字が削除されます。

0