2016-12-07 10 views
0

私は「www.google.comを置き換えますしたい、そして、この私はスクリプトで複数20kのファイルの名前を変更したいのですが、それが失敗した:「引数リストが長すぎる」

for((i=0;i<20000;i++) 
do 
touch "www.google.com electronic&information this is bash test ${date} .txt" 
done 

でこれらのファイルを作成"から" HNSD "に変更されます。は20kファイルで、すべてのファイル名に空白が含まれています。


私の最初の試みは、以下の通りであった:

rename 's/www.google.com/HNSD/g' * 

...しかし、これは "引数リストが長すぎる" エラーを生じました。


私の第二の試みは、以下の通りである。

#!/bin/bash 
function _rename() 
{ 
while read line1; do 
#rename 's/www.google.com/HNSD/g' $line1 
sed -i "s/www.google.com/HNSD/g" $line1 
#echo $line1 
done 
} 

ls -1 | _rename 

...しかし、これは与えられたファイルの名前を変更しません。これはどのように行うべきですか?

+0

'LSを使用しないでください-1'スクリプトで。その前に 'IFS ='を付けずに 'read'を使い、その後に' -r'引数を使用しないでください。引用符で囲まれていない引数は使用しないでください。また、引数リストが長すぎる場合(例えば、 'sed'のような)単一の行として渡された1行に収まるよりも長い引数リストを持たない限り、エラーをどのように受け取るのかははっきりしません。エラーは個々の外部コマンドのargvに基づいています。 –

+0

'sed -i'はファイルの名前を変更しません。むしろ内容が変化するので、このスクリプトがあなたの目標をどのように達成するのかは不明です。 –

+0

また、 'function'キーワードを使用しないでください。互換性のある構文よりも利点を追加することなく、コードがPOSIX shと互換性がなくなります。 –

答えて

1

ファイルごとに1つのコマンドを実行しても、ファイル名自体が長すぎる(または環境がいっぱいで、空き領域がいっぱいになり、argvを共有している)コマンドライン上の宛先名をすぐに指定します。以下は、このように、一般的に非常に安全である:ここでは

for f in *www.google.com*; do 
    mv "$f" "${f//www.google.com/HNSD}" 
done 

、我々は、名前の変更操作を実行するためにparameter expansionを使用しています。それは一度にコマンドラインですべてのファイル名を入れてみましたので


元のコードでは、問題がありました。 xargsまたはfind -exec {} +を使用して操作を複数の呼び出しに分割すると、その問題は発生しません。あなたはrenameを持っており、現在の場所のすべてのディレクトリエントリを処理することが可能と数回としてそれを呼び出したい場合は、それは次のようになります。

printf '%s\0' * | xargs -0 rename 's/www.google.com/HNSD/' 
1

つのオプション:


使用をfind、及び-execアクション内rename(または類似の)を使用して、名前を変更:

find . -type f -name '*www.google.com*' -exec rename 's/www.google.com/HNSD/g' {} + 

活用したファイルを反復するforループ:

for f in *www.google.com*; do rename 's/www.google.com/HNSD/g' "$f"; done 
関連する問題