私のフォルダとサブフォルダ名から「.」を削除したいです。
「Archive.1」というフォルダがあります。 「Archive.2」(など)には「Document.1」などのフォルダがあります。 (etc...)、「Document.1」などのフォルダがあります。 「.」を全て削除したい。内部には「Archive1」と「Document1」があります。
次に始まるスクリプトがあります。
for f in *.mp4; do fn=`echo $f|sed 's/\.//g'`; mv "$f" "$fn"; done
しかし、私がいるフォルダだけをナビゲートします。
助けてください?
よろしくお願いします。
答え1
find
(デフォルトでは)サブツリー全体を再帰的に検索することができます。
find -depth -type d -name '*.*' |
while read f
do
dn=`dirname "$f"`
bn=`basename "$f"`
mv "$dn/$bn" "$dn/${bn//.}"
done
このfind
コマンドは、以下を含む一致する名前を意味します.
。この-depth
オプションを使用すると実行されます。後順位巡回現在のディレクトリツリーでは、つまりそのディレクトリ自体より前のすべてのディレクトリの内容が確認されるため、a.b/c.d
他の一致ディレクトリを含む一致ディレクトリ(たとえば "")が一致として出力されます。後ろに子と一致しますa.b/c.d
。a.b
これがないと、find
パスの一部が途中で変更される可能性があることを知らないか考慮せずにリスト全体が生成されるため、ループが失敗する可能性があります。ループはプリコンパイルされたリストでのみ機能し、 " a.b
" -> " ab
"を実行してから実行しようとします。 " a.b/c.d
" -> " a.b/cd
"。 Postorder Traversalはこの問題を解決できます。
Bashでスペースを含むファイル名を処理することは、スペースを引数区切り文字として扱う傾向があるため、常に苦痛です。上記の方法は、read
改行文字のみを区切り文字として扱う組み込み関数を使用してこの問題を解決します。
フルパス名ではなく各ディレクトリの名前に対してのみ操作を実行したいので、これをいくつかの部分に分割します。今後最後のスラッシュ ("dirname") と実際のファイル名 ("basename") で、基本名でのみ機能します。
また、パターン置換を使用すると、外部フィルタを使用せずに変換を簡単に処理できます。一般的な形${parameter/pattern/string}
は、に比べておなじみに見えるべきですsed
。ただし、ここでは、他のスラッシュで始まるものは、同様にすべてのpattern
一致を置き換える必要があることを示すために使用されます。また、空なので前のスラッシュを省略できます。/g
sed
string
なぜ一致させようとしているのかよくわかりません*.mp4
。.mp4
ファイルのあるパスのみをお探しですか?その場合、状況は少し複雑になります。まず、そのファイルのパス名のリストを作成し、そのファイルからディレクトリパス名のリストをフィルタリングし、正しい順序で作業していることを確認する必要があります。