Добавить в файлы

Я новичок в Linux, и я пытаюсь решить эту проблему. У меня есть каталог, полный файлов. Моя цель – добавить текст в начало файла. Текст, который идет в начале, одинаковый для каждого файла. Это моя попытка

#!/bin/bash for file in `find . -type f -executable`;do sed '/\#!/bin/bash\/a Hello Word' done 

Мой скрипт ничего не делает, кроме аварии Пожалуйста, помогите

3 Solutions collect form web for “Добавить в файлы”

 #!/bin/bash for file in `find . -type f -executable`;do sed '/\#!/bin/bash\/a Hello Word' fi done 

У этого сценария много проблем.


Во-первых, это не допустимый сценарий Bash, потому что у вас есть fi без соответствующего if .


Стилистически (после удаления строки fi ) я бы удалил пустую строку перед тем, как done и добавьте пробел до do . Но это относительно тривиально.


Теперь, что касается лучших практик, вы используете backticks для замены команд, а не рекомендованной современной формы, $(...) . Backticks поддерживаются исключительно по историческим причинам и не рекомендуются для каких-либо новых скриптов; видеть:

  • У вас есть backticks (т.е. `cmd`) в * sh оболочках устарели?

У вас есть проблема надежности в том, что вы зацикливаетесь на выходе find -a очень плохой идеи и совершенно ненужны. Ваш скрипт будет разбит на любые имена файлов, содержащие пробельные символы или специальные символы. Видеть:

  • Почему происходит перебор находок на выходе плохой практики? )

Если вы хотите, чтобы ваш скрипт был переносимым, вы должны придерживаться определенных функций POSIX, когда это возможно. В частности, для POSIX не указывается первичный -executable для выполнения . -perm +700 этого используйте вместо него -perm +700 .

Также в сфере переносимости использование команды «добавить» для Sed ( a ) без следующей последовательности \<newline> работает в GNU Sed, но не является стандартным.


Вы устанавливаете переменную file в своем цикле for на имя каждого файла по очереди (при отсутствии специальных символов или пробелов в именах файлов, что приведет к тому, что file переменная будет содержать то, что не является именем файла), но вы никогда не используете переменная file .

Команде Sed не предоставляется файл для запуска, поэтому он будет пытаться работать на стандартном входе. Таким образом, при запуске скрипта он просто ждет ввода.


Сам скрипт Sed является неправильным, независимо от того, что ему не хватает имени файла для работы.

Если вы используете / в качестве разделителя для регулярного выражения (что наиболее обычно), вам нужно обратная косая черта – исключить все экземпляры / которые встречаются в регулярном выражении. Единственная часть вашей команды, которая будет читаться как регулярное выражение, – /\#!/ , А остальная часть (начиная с bin ) будет интерпретироваться как команда Sed.

Вместо этого обычным решением было бы заменить каждый / другой, чем окончательный разделитель регулярных выражений, на \/ . (Я вижу, что вы избежали только последней косой черты, которой не следует избегать.)

В Sed есть малоизвестная функция , которую вы можете использовать в своих интересах здесь. Любой символ (кроме обратной косой черты или новой строки) может использоваться как разделитель регулярных выражений, а не только слэш. Поэтому вместо использования /#!\/bin\/bash/ в качестве Sed-адреса вы можете использовать эквивалент \:#!/bin/bash:


Теперь, если вы обработали все вышеперечисленные моменты, у вас будет рабочий скрипт. Возможно, он не делает того, что вы хотите , но на самом деле он что-то сделает . Такой скрипт будет выглядеть так:

 #!/bin/bash find . -type f -perm -700 -exec sed '\:#!/bin/bash:a\ Hello World' {} + 

Что делает этот скрипт? Он рекурсивно ищет текущий каталог для всех файлов с установленным битом (для владельца) и для каждого такого файла печатает весь файл с текстом Hello World добавленным после любых строк, содержащих текст #!/bin/bash .

Sed на самом деле не предназначен для редактирования файлов на месте; это Редактор потока. GNU Sed позволит вам редактировать файлы на месте с помощью ключа -i , но я бы просто использовал стандартный инструмент ex для редактирования файлов.


Но здесь есть еще один момент. Если вы хотите добавить строку Hello World в сценарий Bash, она фактически ничего не сделает, поскольку Hello не является допустимым именем команды. Возможно, вы хотите напечатать текст «Hello World» в сценарии Bash, другими словами, добавить echo "Hello World , который может иметь смысл.

Теперь мы находимся в сфере уточнения того, что должен делать ваш сценарий.


Заключительный сценарий

Таким образом, моя более точная формулировка спецификаций для этого скрипта:

  • Сценарий должен найти все обычные файлы в текущем каталоге (или в любом подкаталоге рекурсивно), для которого установлен исполняемый бит для владельца.
  • Для каждого такого файла скрипт должен проверить, соответствует ли первая строка файла строке #!/bin/bash .
  • Только для файлов с этой точной первой строкой сценарий должен вставить точный текст echo "Hello World" , за которым следует символ новой строки, после первой строки файла. (Это изменение должно быть сохранено в файле, а не напечатано до стандартного.)

Вот сценарий, соответствующий этим точным спецификациям, используя только инструменты и функции POSIX:

 #!/bin/sh find . -type f -perm -700 -exec sh -c ' for f do head -n 1 "$f" | grep -qFx "#!/bin/bash" && printf "%s\n" "1a" "echo \"Hello World\"" . x | ex "$f" done ' find-sh {} + 

чего вы пытаетесь достичь? чтобы узнать исполняемые сценарии, используйте команду ниже

 find . -type f -perm /u+x,g+x,o+x | while read file do filename=$(echo ${file} | awk -F/ '{print $NF}') echo "File Name : ${filename}" done 

Если вы пытаетесь добавить Hello World после строки shebang, тогда ваша команда sed должна быть

  sed '/\#!/bin/bash/a Hello Word' ${file} 

если вы хотите внести изменения в сам файл, добавьте -i в команду sed

find . -type f -executable -exec sed '/^#!\/bin\/bash/a Hello World' {} \;

  • Извлечение запросов из файла журнала, которые не включают запрещенные строки
  • Как передать переменную в скрипте через терминал при выполнении abc.sh
  • Asteriks в имени файла, поскольку wildcard не работает
  • массив считывания и суммирование элементов
  • bash script «Нет такого файла ...»
  • Как проверить, соответствует ли имя файла шаблону?
  • Выполнение почтовой команды внутри функции вызывает «вилку»,
  • Как перенаправить вывод команд Linux на конкретную строку и столбец в csv?
  • Это ошибка в bash? `return` не выходит из функции, если вызывается из канала
  • Grep все строки из нескольких двоичных файлов в один файл txt
  • Поиск данных из всех файлов в папке
  • Interesting Posts

    Командная подсистема Bash с переменной окружением

    Изменить громкость с помощью терминала

    Python 26 pkg отсутствует в CentOS 5

    Возможно ли chroot sftp service как непривилегированный пользователь?

    Сценарий для перемещения одного типа файлов и создания подпапки, если он существует?

    Отправлять трафик через другой узел

    Как GNOME не удалось установить мой USB-накопитель для восстановления Windows?

    Безопасно ли использовать tar, даже если в именах файлов и путях есть некоторые символы, отличные от ASCII?

    Зачем мне читать с ленты 3 раза, чтобы читать 2 архива?

    DROP все для порта 22, если не geoip набор из США для iptables и xtables

    Оператор if внутри оператора case

    как смонтировать внешний жесткий диск, подключенный через SATA-провод к CentOS 7

    Сценарий для чтения видео и информации о выходе

    Сопоставьте ключ символа с некоторым ключом-модификатором ?

    вставить значение в конце каждой записи на основе уникальных идентификаторов

    Linux и Unix - лучшая ОС в мире.