1

まず第一に、これは私の最初の投稿であり、私が完全な Linux 初心者であることを明記しなければなりません。

最近、オフィス用に QNAP NAS ボックスを購入しました。このボックスには、古い Mac XServe マシンからコピーされた大量のデータがあります。多くのファイルとフォルダーには、もともと名前にスラッシュが含まれていました (HFS+ では、そもそもこれを許可するべきではありませんでした)。これは、NAS にコピーされたときに、すべてコロンに置き換えられました。

すべてのコロンの名前をアンダースコアに変更したいのですが、ここの別のスレッドで次のコマンドを見つけました: bash でファイルの名前を変更する際の落とし穴

ただし、このボックスに搭載されている Linux のフレーバーは名前変更コマンドを認識しないため、代わりに mv を使用する必要があります。以下のコードを使用してみましたが、これは現在のフォルダー内のファイルに対してのみ機能します。これを変更してすべてのサブフォルダーを含める方法はありますか?

for f in *.*; do mv -- "$f" "${f//:/_}"; done

find次のコマンドを使用して、問題のファイルとフォルダーをすべて見つけることができることがわかりました

ファイル:

find . -type f -name "*:*" 

フォルダ:

find . -type d -name "*:*"

を使用して、上記の結果のリストをエクスポートできました

find . -type f -name "*:*" > files.txt

以下のコマンドを使用してみましたが、find からスイッチが認識されないというエラー メッセージが表示されます。execこれをすべて 1 つのコマンドにパイプする方法はありますか、または以前にエクスポートしたファイルを何らかの方法で使用できますか?

find . -depth -name "*:*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//:/_}"' _ {} \;

ありがとうございました!ヴィンセント

4

1 に答える 1

1

したがって、for ループ コードは機能しますが、現在のディレクトリでのみ機能します。また、find を使用して、ファイル名に : を含むすべてのファイルを含むファイルを作成することもできます。

したがって、これはすべて既に行っているので、ファイルの各行をループして、同じ mv コマンドを実行します。

このようなもの:

for f in `cat files.txt`; do mv $f "${f//:/_}"; done

編集:

tripleee が指摘したように、while ループを使用する方がより良い解決策です

例えば

while read -r f; do mv "$f" "${f//:/_}"; done <files.txt

お役に立てれば。

意思

于 2013-07-11T11:13:56.623 に答える