目的
これらのファイル名を変更します。
これらのファイル名に:
シェルコード
テストする:
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/
何も思いつきません。このコードを本当に理解したいです。ここで私を助けてください、みんな。
まず、これを行う最も簡単な方法は、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回実行した場合など、ファイル名から文字が吸い出されることはありません。
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
数年前に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
などとして使用できます。
最も簡単な方法は次のとおりです。
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/15
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
等々。
バックスラッシュとパレンの意味は、「パターンを一致させながら、ここで一致するものを保持する」ということです。後で、置換テキスト側で、「\ 1」(最初の括弧で囲まれたブロック)、「\ 2」(2番目のブロック)などで、それらの記憶されたフラグメントを取得できます。
ここに私がやることがあります:
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
かっこは、バックスラッシュ番号で使用する特定の文字列をキャプチャします。
ls F00001-0708-*|sed 's|^F0000\(.*\)|mv & F000\1|' | bash
あなたが本当にしているのが、2番目の文字を削除することである場合、それが何であるかに関係なく、あなたはこれを行うことができます:
s/.//2
ただし、コマンドはmv
コマンドを作成し、実行のためにシェルにパイプします。
これはあなたのバージョンよりも読みにくいです:
find -type f | sed -n 'h;s/.//4;x;s/^/mv /;G;s/\n/ /g;p' | sh
find
が各ファイル名の先頭に「./」を付けているため、4番目の文字が削除されます。