Здесь вы используете множество плохих практик: отсутствие цитат, вы разбираете вывод ls
... все это сломается, как только имя файла содержит пробел другого смешного символа.
Вам не нужна рекурсия, если вы используете bashglobstar
по желанию, или find
.
Вот возможность с бывшим, что мы надеемся показать вам лучшие практики:
#!/bin/bash
shopt -s globstar
shopt -s nullglob
funk() {
local search=${2//\//\\/}
local replace=${3//\//\\/}
for f in "$1"/**.txt; do
sed -i "s/$search/$replace/g" -- "$f"
cp -nvt "$4" -- "$f"
done
}
if (($#!=4)); then
echo >&2 "Need 4 arguments"
exit 1
fi
funk "[email protected]"
Та же функция фанк с помощью find
:
#!/bin/bash
funk() {
local search=${2//\//\\/}
local replace=${3//\//\\/}
find "$1" -name '*.txt' -type f -exec sed -i "s/$search/$replace/g" -- {} \; -exec cp -nvt "$4" -- {} \;
}
if (($#!=4)); then
echo >&2 "Need 4 arguments"
exit 1
fi
funk "[email protected]"
В cp
я использую
-n
переключатель: нет clobber, чтобы не перезаписывать существующий файл. Используйте его, если ваша версия mv
поддерживает его, если вы на самом деле не хотите перезаписывать файлы.
-v
switch: verbose, покажет вам перемещенные файлы (необязательно).
-t
переключатель: -t
, за которым следует каталог, сообщает, что копировать в этот каталог. Очень полезно использовать cp
следующим образом: представьте, вместо того, чтобы предоставить существующий каталог , вы даете существующий файл : без этой функции этот файл будет перезаписан несколько раз (ну, это будет так, если вы опустите опцию -n
)! с этой функцией существующий файл останется в безопасности.
Также обратите внимание на использование --
. Если ваши cp
и sed
поддерживают его (в случае с GNU sed
и cp
), используйте его всегда!это означает конец опций теперь. Если вы не используете его, и если имя файла начинается с дефиса, это смущает команду, пытающуюся интерпретировать опцию. С помощью этого --
мы можем указать имя файла, которое может начинаться с дефиса.
Обратите внимание, что в поиске и заменить шаблонов Я заменил все слэшами /
их сбежавшей формой \/
, чтобы не конфликтовать с разделителем в sed
если слэш происходит появляться в поиске или заменить ,
Наслаждайтесь!
Ваш код сломается, как только появится имя файла/каталога, содержащее пробелы. См. [Здесь] (http://mywiki.wooledge.org/ParsingLs) для более подробного объяснения, почему вы никогда не должны использовать 'ls', как вы это делаете в своем коде. –
В вашем вопросе не уточняется, что не работает. Может быть, это мои глаза, но ваши требования и ваше описание того, что делает сценарий, кажутся одинаковыми. – innaM