Unix: самый простой способ рекурсивной замены блока многострочного текста - PullRequest
1 голос
/ 29 июня 2011

Я хотел бы изменить текст лицензии, появляющийся в начале сотен исходных файлов. Какой самый простой способ сделать это?

Редактировать: Вот иллюстрация того, что я пытаюсь сделать:

Старый файл:

License 1:
xxxxxxxxxxxxx
xxxxxxxxxxxx
xxxxxxxxxxxx
xxxxxxxxxxxx
public class Foo
{



};

Новый файл:

License 2:
yyyyyyyyyyyyyy
yyyyyyyyyyyyyy
yyyyyyyyyyyyyy
yyyyyyyyyyyyyyy
public class Foo
{



};

Итак, текст после лицензии должен остаться без изменений.

Спасибо!

Ответы [ 6 ]

1 голос
/ 30 июня 2011

Если вы можете определить последнюю строку из licence1 (например, если она не пустая строка или около того), вы можете сделать это, например, с помощью:

sed '1,/^the last line$/d' < $origfile | cat newlic.txt - > $newfile
0 голосов
/ 30 июня 2011

Вам понадобится эта команда sed для замены в верхней части ваших файлов:

sed -i -n '/\(License\)/,/\(public class\)/{1h;1!H;/public class /{;g;s/\(License\).*\(public class \)/\1 2:\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyyyy\n\2/;p;};};/\(License\)/,/\(public class\)/!p' file.txt

Теперь, чтобы сделать это рекурсивно, вы можете объединить приведенное выше с поиском (при условии, что вы делаете это в .txt файлах):

find . -name "*.txt" -exec sed -i -n '/\(License\)/,/\(public class\)/{1h;1!H;/public class /{;g;s/\(License\).*\(public class \)/\1 2:\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyy\nyyyyyyyyyyyyyyyy\n\2/;p;};};/\(License\)/,/\(public class\)/!p' {} \;
0 голосов
/ 29 июня 2011

Это хорошее место, чтобы использовать ed скрипт.

Что-то вроде:

for i in *.java; do
  ed $i << \eof
1,20d
0r newlicense.txt
w
q
eof
done

Вероятно, это хорошая идея, чтобы обернуть это так, чтобы он проверял старую лицензию. Вы можете сделать это условным для grep для строки в старой лицензии или, возможно, изменить 1,20d на что-то вроде /first old line/;/last old line/d

0 голосов
/ 29 июня 2011

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

Он имеет дело со строчными префиксами, так что если ваши файлы bash используют # комментарии, а ваши программы на C// и ваш SQL - - он установит правильный префикс на месте (используя все, что использовалось ранее).

Другим приемом было использование ©.Некоторые файлы были закодированы в UTF-8, поэтому я мог использовать ©, другие были закодированы в латинском-1, поэтому я использовал символ латинского-1, другие были закодированы в простой ascii, поэтому я использовал (c).

Последним трюком был диапазон дат авторского права.Copyright © 1997-2011.Разные поколения менеджмента хотели здесь разных ценностей.С начала компании до этого года, с даты создания файла до этого года, индивидуальный список каждого года, в котором файл обновлялся, и т. Д.

0 голосов
/ 29 июня 2011

Вы говорите, что ваш текст "License" появляется в верхней части исходных файлов.Для этого вы можете сохранить старую лицензию в одном файле, а новую - в другом.Затем запустите следующий скрипт bash.

dir=/home/priyank/temp/*.c #for all c files in the temp directory
for f in $dir
do
    filename=$f
    temp="$filename""__temp"
    cat new.txt > $temp #new.txt is new license
    v=`cat old.txt | wc -l`; #old.txt is old license
    awk '
    NR>'$v'{
    print $0 >> "'$temp'";
    }
    ' $filename
    rm $filename
    mv $temp $filename
done

Запустите это как bash script.sh.Кроме того, , пожалуйста, сохраните ваши оригинальные файлы где-нибудь перед тем, как попробовать этот скрипт.Работает быстро.Я взял этот в качестве файлов, и он работал отлично.Не забудьте не добавлять лишние новые строки в старый файл лицензии.

0 голосов
/ 29 июня 2011

Вы можете попробовать что-то вроде этого:

newText="<your new license text>";

for file in <your files>
do
   sed '1,<number of lines of your old license text>d' $file |awk -v TEXT="$newText" 'BEGIN {print TEXT}{print}' > "${file}.tmp";
   mv "${file}.tmp" $file 
done
...