Как добавить текст в начало и конец нескольких текстовых файлов в Bash?

24

У меня есть каталог, полный текстовых файлов. Моя цель - добавить текст в начало и конец всех из них. Текст, который идет в начале и в конце, одинаков для каждого файла.

Основываясь на коде, который я получил из Интернета, это код для добавления в начало файла:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

Это код для добавления в конец файла. Цель состоит в том, чтобы добавить текст };в конце каждого файла:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

Примеры, которые я использовал, были для отдельных файлов. Я думал, что попробую действовать на несколько файлов, используя подстановочный знак *.txt.

Возможно, я делаю и другие ошибки. В любом случае, как добавить текст в начало и конец нескольких файлов?

интервьюер
источник

Ответы:

27

Чтобы добавить текст в файл, который вы можете использовать (с реализацией GNU sed):

sed -i '1i some string' file

Добавить текст так же просто, как

echo 'Some other string' >> file

Последнее, что нужно сделать, это поместить это в цикл, который перебирает все файлы, которые вы собираетесь редактировать:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done
Marco
источник
8

Вы можете использовать GNU sed

Как уже было показано, вы можете вставить строки текста непосредственно до и после сопоставления строк файла с sedпомощью команды iи aсоответственно. Что не было показано, так это то, что вы можете сделать это с помощью одной строки и для нескольких файлов одновременно.

Далее будет вставлена ​​строка до первой 1iи после последней строки $a. Вставки будут выполнены для всех файлов, соответствующих глобу *.txt.

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

И то, iи другое работает aне только с номерами строк, но и с каждой строкой, соответствующей заданному шаблону. Это добавит комментарий, если строка содержит var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js
Дж. Кацвинкель
источник
5

Полностью POSIX-совместимая команда, использующая ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

Если вы выполните printfчасть команды самостоятельно, вы увидите точные команды редактирования, которым она передает ex:

0a
var language = {
.
$a
};
.
x

0aозначает «Добавить текст после строки 0» (другими словами, перед первой строкой). Следующая строка - это буквальный текст, который «добавляется» после строки 0. Точка ( .) в строке сама заканчивает добавляемый текст.

$a означает добавить текст после последней строки файла.

x означает сохранить изменения и выйти.

Wildcard
источник
2

Вот способ сделать это в Perl:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done
Тердон
источник
@ StéphaneChazelas добавление -iвместо этого файла подстановка не работает, он просто печатает на стандартный вывод.
Олег Припин
@OlehPrypin, действительно ваше право. Комментарий удален.
Стефан Шазелас
1

Попробуйте использовать ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

где команды:

  • bufdo!выполняет команды ниже для каждого открытого буфера / файла (примечание: это не POSIX )
  • 1s/^/HEAD/- вставляет HEADтекст в первую строку в начале строки
  • $s/$/TAIL/- добавляет TAILтекст в последнюю строку в конце строки

и аргументы таковы:

  • -s - тихий / быстрый режим
  • -cxa - сохранить все открытые буферы / файлы и выйти
  • *.foo- все файлы в текущем каталоге ( *) с fooрасширением, использованием **/*.fooдля рекурсии (после включения globstar: shopt -s globstar)
kenorb
источник
1
примечание: bufdo - это не POSIX. pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Стивен Пенни,
1
@ StevenPenny прав. Я лично использую указанные функции POSIX только для скриптовых правок.
Wildcard
1

С gnu awkпомощью inplaceрасширения и BEGINFILE/ ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt
don_crissti
источник
1

Также имеет право быть (с результатами в .outфайлах):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

Другой, более сложный вариант - исходные файлы заменены на результат:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print
ладья
источник
0

Perl однострочник на помощь:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
Кжетил С.
источник