2016-12-07 10 views
0

создать эти файлы с помощью этойя хочу переименовать более 20k файлов с помощью сценария, но он не: «список аргументов слишком длинный»

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

Тогда, я хочу сделать вместо «www.google.com "до" HNSD ". в файлах 20 тыс., Все имена файлов включают пробелы.


Моя первая попытка была следующая:

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' в сценариях. Не используйте 'read' без' IFS = 'перед ним и аргумент' -r' после него. Не используйте аргументы без кавычек. И не ясно, как вы получите эту ошибку, если у вас не было более длинного списка аргументов, чем будет помещено в одну строку, переданную команде (например, 'sed') как * одиночная * строка, поскольку слишком длинный список аргументов, ошибка основана на argv каждой отдельной внешней команды. –

+0

И 'sed -i' вообще не переименовывает файлы; скорее, это изменяет их содержание - так что неясно, как вы ожидаете, что этот скрипт выполнит вашу заявленную цель. –

+0

Кроме того, не используйте ключевое слово 'function' - это делает ваш код несовместимым с POSIX sh без добавления каких-либо преимуществ по сравнению с совместимым синтаксисом. –

ответ

1

Запуск одной команды mv не вызывает этой проблемы, если сами имена файлов не слишком длинны (или ваша среда настолько заполнена, таким образом вытесняя пространство, разделенное с использованием 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, и переименовать с помощью rename (или аналогичного) в пределах -exec действий:

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 

 Смежные вопросы

  • Нет связанных вопросов^_^