104

目的

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

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

これらのファイル名に:

  • F0001-0708-RG-biasliuyda
  • F0001-0708-CS-akgdlaul
  • F0001-0708-VF-ヒオルギグル

シェルコード

テストする:

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/

何も思いつきません。

4

13 に答える 13

170

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

Ubuntu、OSX (Homebrew パッケージrename、MacPorts パッケージp5-file-rename)、または perl rename (prename) を使用するその他のシステム:

rename s/0000/000/ F0000*

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

rename 0000 000 F0000*

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

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

  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

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

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

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

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

于 2010-03-03T15:55:16.333 に答える
53

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
于 2010-03-03T16:02:40.933 に答える
37

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

于 2013-06-22T18:40:28.147 に答える
25

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

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

または、ポータブルに、

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

これによりF00001、ファイル名のプレフィックスがF0001. こちらの mahesh のクレジット: http://www.debian-administration.org/articles/150

于 2013-09-01T11:02:15.987 に答える
8

sedコマンド_

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

交換することを意味します:

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

と:

mv & \1\2

通常のsedコマンドのように。ただし、括弧&\nマーカーはそれを少し変更します。

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

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

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

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

等々。

于 2010-03-03T16:05:33.673 に答える
3

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

于 2010-03-03T15:54:57.147 に答える
1

これが私がすることです:

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
于 2013-08-27T22:59:43.660 に答える
1

実際に行っているのが 2 番目の文字を削除することだけである場合は、それが何であるかに関係なく、次のようにすることができます。

s/.//2

しかし、あなたのコマンドはコマンドを構築し、mvそれをシェルにパイプして実行しています。

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

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

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

于 2010-03-03T17:12:37.677 に答える
0
 ls F00001-0708-*|sed 's|^F0000\(.*\)|mv & F000\1|' | bash
于 2010-03-04T07:13:51.473 に答える
0

括弧は、バックスラッシュ付きの数字で使用する特定の文字列をキャプチャします。

于 2010-03-03T15:55:34.103 に答える