Перепишите команду find, которая использует sed -i для AIX

У меня есть скрипт, который ищет строку и заменяет ее командой sed. Если эта строка содержит специальные символы, сценарий будет скрыт от них (кроме косой черты, потому что это мой текущий разделитель для sed и столбца, потому что он отмечает строку в строке bash).

Вот оно:

raw_searchstring='SearchForThis'; raw_replacementstring='ReplaceWithThis'; #Escape special characters: quoted_searchstring=$(printf %s "$raw_searchstring" | sed 's/[][()\.^$?*+]/\\&/g'); quoted_replacementstring=$(printf %s "$raw_replacementstring" | sed 's/[][()\.^$?*+]/\\&/g'); find ./ -type f -exec sed -i -r "s/$quoted_searchstring/$quoted_replacementstring/" {} \; 

Я тестировал это на Ubuntu, и он работал отлично.

Однако мне нужно запустить скрипт в системе AIX. Поскольку он не поддерживает встроенное редактирование с помощью sed -i, я попробовал следующее, как было предложено по аналогичному вопросу ( AIX's sed – in place editing ):

 find ./ -type f -exec sed -r 's/$quoted_searchstring/$quoted_replacementstring/' infile > tmp.$$ && mv tmp.$$ infile {} \; 

Вот где я получаю ошибку

 find: missing argument to `-exec' 

поэтому я попытался передать более одной инструкции -exec, чтобы find этой строке:

 find /home/tobias/Desktop -type f -exec sed -r 's/$quoted_searchstring/$quoted_replacementstring/' infile > tmp.$$ {} \; -exec mv tmp.$$ infile {} \; 

это тоже не работает:

 sed: can't read infile: No such file or directory 

Я не уверен, что я сделал неправильно. Можете ли вы помочь мне исправить эту строку кода или указать мне в правильном направлении?

  • Чтение .zshrc в X сеансе открыто? / Как выполнить скрипт в X сеансе открытия?
  • Bash назначает вывод / ошибку переменной
  • Как запустить ulimit в скрипте с другим приложением
  • Как скопировать все файлы в папку, за исключением файлов, которые записываются?
  • Ошибка сценария слияния FFMPEG
  • Скрипт для обеспечения работы только одного экземпляра Oracle
  • Как использовать: cat << EOF
  • Ведение журнала консоли с использованием команды сценария вывод нечитабельно
  • One Solution collect form web for “Перепишите команду find, которая использует sed -i для AIX”

    Ваши попытки не работают, потому что вы пытаетесь использовать операторы оболочки, такие как && и > в команде, выполняемой find , но вы вводите эти операторы непосредственно в команде, поэтому они выполняются оболочкой, которая вызывает find , Ваши команды анализируются как

     find … > tmp.$$ && mv … 

    например, первый вызов find

     find ./ -type f -exec sed 's/$quoted_searchstring/$quoted_replacementstring/' infile 

    с выходом, перенаправленным на tmp.$$ . Существуют и другие проблемы с командой: infile должно быть {} (это найденный файл), а одиночные кавычки вокруг выражения sed должны быть двойными кавычками, поскольку вы используете там переменные оболочки.

    Поскольку вам нужно использовать конструкторы оболочки в команде, которая выполняется find , скажите find чтобы выполнить оболочку.

     find … -exec sh -c '…' {} \; 

    Чтобы избежать трудностей с цитированием, передайте вещи, которые требуют цитирования, такие как выражение sed, в качестве аргументов sh .

     find ./ -type f -exec sh -c ' sed "$0" "$1" >"$1.new" && mv "$1.new" "$1" ' "s/$quoted_searchstring/$quoted_replacementstring/" {} \; 

    Для небольшого повышения производительности при небольшой разборчивости текста вы можете использовать форму -exec … {} + и цикл оболочки.

     find ./ -type f -exec sh -c ' for x; do sed "$0" "$x" >"$x.new" && mv "$x.new" "$x"; done ' "s/$quoted_searchstring/$quoted_replacementstring/" {} + 

    В качестве альтернативы, если версия ksh93 на вашей AIX не слишком древняя, вы можете использовать ее рекурсивную функцию globbing (введенную в ksh93p).

     set -G for x in **; do [[ -f $x ]] || continue sed "s/$quoted_searchstring/$quoted_replacementstring/" "$x" >"$x.new" && mv "$x.new" "$x"; done 

    В любом случае, обратите внимание, что вам также потребуется настроить преобразование строк в регулярное выражение для создания основного регулярного выражения, поскольку флаг -r для использования ERE является расширением GNU. Также у вашего существующего кода есть несколько ошибок: вы забыли процитировать косые черты, и вы не указываете правильные символы в заменяющем тексте.

     quoted_searchstring=$(printf %s "$raw_searchstring" | sed 's![[\/.^$*]!\\&!g'); quoted_replacementstring=$(printf %s "$raw_replacementstring" | sed -e 's![][\/&]!\\&!g' -e '!$ s!$!\\!'); 
    Interesting Posts
    Linux и Unix - лучшая ОС в мире.