sed: вставка текста перед концом раздела <HEAD>

Со статистикой OSX:

for file in *; do
    dir="$(stat -t %Y%m%d%H%M%S -f %Sm -- "$file")"
    mkdir -p "$dir"
    mv -- "$file" "$dir/$file"
done

Со статистикой GNU (т.е. на Linux или Cygwin):

for file in *; do
    dir="$(stat -c %Y -- "$file")"
    mkdir -p "$dir"
    mv -- "$file" "$dir/$file"
done

Это переместит каждый файл в каталог, названный с его mtime (как эпоха).

Если Вы хотите более прекрасное гранулярное управление тем, как каталог смотрит, можно использовать дату GNU для переформатирования его путем изменения строки присвоения на что-то вроде этого:

dir="$(date -d @"$(stat -c %Y -- "$file")" +%F)"

Посмотрите man date для получения информации о спецификациях формата даты, которые можно использовать. В этом случае, %F :

%F полная дата; то же как %Y-% m-% d

4
12.04.2015, 07:49
2 ответа

В месте sed требуется сделать резервную копию файла во время процесса. Опция -i на Apple's sed требует аргумента расширения (для создаваемого им файла резервной копии) и потребляет следующий аргумент. Это означает, что вы говорите ему, что хотите, чтобы он создал резервную копию с расширением "#s#..... ".

Ошибка означает, что она думает, что вы ссылаетесь на команду append. Я догадываюсь, что значение $1 начинается с a. Потому что -i съел предыдущий аргумент sed думает, что это и есть выполняемый скрипт, а не путь к файлу, который нужно изменить, и вы получаете ошибки соответственно. Именно такую ошибку вы бы получили с помощью Apple sed и недействительной команды a:

$ sed a
седан: 1: "a": команда a ожидает \ с последующим текстом.

Предоставьте аргумент расширения для -i в вашей команде sed:

sed -i.bak "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 50px ! important;} </style>\n</head>#" "${1}/${2}/${i}.html"

и все сработает (хотя обратите внимание, что \n не является экранированием новой строки). Если вы используете одинарные кавычки, вы можете даже вынуть пробел из "!important".

Вышеуказанное будет работать и в GNU sed, но обратите внимание, что -i не является опцией POSIX и, как правило, не переносится.

Часто рекомендуется все равно не использовать встроенную модификацию и работать с копией файла явно самостоятельно. Однако, это зависит от вас.


Вам следует процитировать расширения переменных ${1} и т.д. Цитировать только косые черты бессмысленно, потому что они всегда буквальны.

4
27.01.2020, 20:49

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

Чтобы безопасно i вставить или a добавить произвольную строку в начало / конец строки с sed , у вас есть несколько вариантов, каждый больше сложнее, чем последнее.

Первая и самая простая из всех - это команда r ead. Это требует нулевого экранирования. Например, если строка, которую вы хотите добавить, находится в файле ./ append , вы можете просто сделать:

sed '\|</head>|r ./append' <infile >outfile

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

sed -e '$!N;\|\n</head>|r ./insert' -e 'P;D' <infile >outfile

Но r ead предназначен для записи в стандартный вывод - и я не уверен, как это будет работать с - i nplace option (в любом случае, на мой взгляд, это просто уродливый хакер) . Я предполагаю , что sed должен делать то же самое, что и с p rint, и перенаправлять stdout в свой именованный -i nplace edit файл .

Другой вариант - использовать команду a ppend - для добавления то есть.Чтобы сделать это безопасно, вам нужно только экранировать \ n ewlines и обратную косую черту. Вы можете сделать это примерно так:

printf %s\\n "$str_to_append" |
sed 's|\\|&&|g;$!s|$|\\|;1i\
    \\|</head>|a\\' |
sed -f - infile >outfile

ppend, однако, должен вести себя так же, как r ead, поэтому я снова не уверен, как он может вести себя в -i n-place hack.

Если вы замените a \\ выше на i \\ , он i вставит текст в стандартный вывод (или с именем -i nplace edit-file - если это работает для вашей реализации) перед записывается пространство шаблонов.

Если вам нравится дополнительная работа, (или, в единственном практическом применении, которое я могу придумать, вы планируете несколько r eads / a ppends на строку в в определенном порядке) его также можно использовать для вставок точно так же, как я делал с r ead раньше:

printf %s\\n "$str_to_append" |
sed 's|\\|&&|g;$!s|$|\\|;1i\
    \\|\\n</head>|a\\' |
sed -e '$!N' -f - -e 'P;D' infile >outfile

Последнее, что я предлагаю, почти идентично, за исключением того, что вы также должны избегать & и разделитель (обычно это / ) . Это может работать следующим образом:

printf %s\\n "$str_to_append" |
sed 's|[\/&]|\\&|g
   $!s|$|\\|;$s|$|/|
     1i\
     /<\\/head>/s/^/\\' |
sed -f - infile >outfile

Это приведет к вставке - вы просто замените ^ на $ , если хотите добавить строку таким образом.

Я почти уверен, что это сработает, добавите вы параметр -i или нет.

И последнее примечание - вместо того, чтобы использовать -i , вы также можете использовать:

sed '$d;\|</head>|r ./append' <<IN >infile
$(   cat <infile; echo .)
IN

... или, для вставки:

sed -e '$d;N;\|\n</head>|r ./insert' -e 'P;D' <<IN >infile
$(   cat <infile; echo .)
IN

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

4
27.01.2020, 20:49

Теги

Похожие вопросы