использование sed для поиска и замены в bash для цикла

#bash #sed

#bash #sed

Вопрос:

У меня есть большое количество слов в текстовом файле для замены.

Этот скрипт работает до тех пор, пока команда sed, в которой я получаю:

sed: 1: «* .js»: недопустимый код команды *

PS… Bash не является одной из моих сильных сторон — это не обязательно должно быть красивым или эффективным

 cd '/Users/xxxxxx/Sites/xxxxxx'
    echo `pwd`;

    for line in `cat myFile.txt`
    do
        export IFS=":"
        i=0
        list=()

        for word in $line; do
            list[$i]=$word
            i=$[i 1]
        done

        echo ${list[0]}
        echo ${list[1]}

        sed -i "s/{$list[0]}/{$list[1]}/g" *.js

    done
 

Комментарии:

1. С точки зрения стиля, echo `pwd` это бесполезное использование Echo; просто pwd будет напечатан текущий рабочий каталог. Аналогично, повторный запуск for цикла cat в backticks — бесполезное использование Cat. Смотрите также partmaps.org/era/unix/award.html

Ответ №1:

Вы используете BSD sed (под OS X), поэтому -i для флага требуется аргумент, указывающий, каким должен быть суффикс.

Кроме того, ни один файл не соответствует *.js глобусу.

Ответ №2:

Это выглядит как простая опечатка:

 sed -i "s/{$list[0]}/{$list[1]}/g" *.js
 

Должно быть:

 sed -i "s/${list[0]}/${list[1]}/g" *.js
 

(точно так же, как в echo строках выше)

Ответ №3:

So myFile.txt содержит список замен from:to, и вы перебираете каждую из них. Почему бы вам вместо этого не создать sed скрипт из этого файла?

 cd '/Users/xxxxxx/Sites/xxxxxx'
sed -e 's/^/s:/' -e 's/$/:/' myFile.txt |
# Output from first sed script is a sed script!
# It contains substitutions like this:
# s:from:to:
# s:other:substitute:
sed -f - -i~ *.js
 

Вам sed может не понравиться -f - , что означает sed , что вы должны прочитать свой скрипт из стандартного ввода. Если это так, возможно, вы можете вместо этого создать временный сценарий, подобный этому;

 sed -e 's/^/s:/' -e 's/$/:/' myFile.txt >script.sed
sed -f script.sed -i~ *.js
 

Ответ №4:

Другой подход, если вы не очень уверены в sed и думаете, что через неделю забудете, что означают эти символы вуду, может заключаться в более эффективном использовании IFS:

 IFS=":"
cat myFile.txt | while read PATTERN REPLACEMENT  # You feed the while loop with stdout lines and read fields separated by ":"
do
   sed -i "s/${PATTERN}/${REPLACEMENT}/g"
done
 

Единственная ошибка, которую я вижу (ее может быть больше), заключается в том, что если ШАБЛОН или ЗАМЕНА содержат косую черту (/), они уничтожат ваше выражение sed.
Вы можете изменить разделитель sed на непечатаемый символ, и вы должны быть в безопасности.
В любом случае, если вы знаете, что на вашем myFile.txt вы можете просто использовать любой.