Вы могли использовать сингл sed
управляйте как в следующем:
FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")
Естественные инструменты для этого являются awk и Perl (предполагающий, что Вы хотите написать сценарий: для некогда прочь, естественный инструмент является интерактивным редактором). Вот awk сценарий, который копирует все CLASS
…END
блоки (никакая балансировка не поддерживала: каждый CLASS
соответствует следующему END
), за исключением того, что foo
строки опущены из второй копии.
awk '
/^CLASS$/ { store = 1; } # start storing
store && ! /^foo$/ { hold = hold ORS $0; } # if storing, maybe save line
/^END$/ {
$0 = $0 hold; # append hold copy to current line
store = 0; hold = ""; # end of block
}
1 { print; } # print original line, with hold prepended if at end of block
'
Вот sed решение; не относитесь к нему слишком серьезно. Не ожидайте, что это будет вести себя если CLASS
/END
строки не находятся в строгом чередовании.
sed -e '/^CLASS$/,/^END$/!b' \
-e '/^CLASS$/{' -e 'h' -e 'b' -e '}' \
-e '/^foo$/!H' \
-e '/^END$/G'
Ну, можно написать сценарий чего-либо.
Однако, если бы я делал это, то я использовал бы vim
макросы. (Если Вы не знакомы с vim
уже, необходимо изучить это, но иначе проигнорировать это),
Несколько основных указателей:
q - начните записывать макрос
qx - прекратите записывать макрос и назовите его 'x'
@x - выполните макрос, названный 'x'
Макрос сразу повторно выполнит любые команды, которые Вы ввели во время сессии записи.
Таким образом, если Вы хотели, чтобы макрос копировал блок как этот тип:
q start macro
/CLASS jump to next "CLASS"
V start selecting full lines
/END jump to next "END
Y yank selected lines (yank = copy)
j scroll down one line
p put (paste)
qd stop recording and name the macro d
Существует много хороших ресурсов и примеров там для использований энергии и макросов энергии.
Если это имеет значение sed - своего рода версия командной строки энергии, таким образом, Вы смогли адаптировать то, что я сказал sed, но я менее знаком с ним, таким образом, я не могу ручаться за него.
~~ редактируют ~~
Другая вещь, которая делает это более полезным, vim
способность открыть несколько файлов. Несколько открытых файлов упоминаются как буферы. Вы активируете это при наличии нескольких имен файлов после vim
(IE vim *.txt
открыть все txt файлы)
Для выполнения макроса на нескольких буферах сначала откройте все файлы одновременно. Затем используйте :bufdo normal @x
выполнять макрос x
на каждом буфере.
Отметьте, Вы должны иметь :w
как последний шаг макроса, который постарается не застревать, когда это пытается переключиться на следующий буфер, если текущий не сохраняется.
:bn
возьмет вручную к следующему буферу.
Кроме того, см. https://stackoverflow.com/questions/1291962/replay-a-vim-macro-until-end-of-buffer для того, как выполнить макрос для каждой строки. Смешивание и подгонка :)
Точный инструмент для использования будет зависеть от специфических особенностей задания. Если задание только собирается произойти однажды, Вы могли бы рассмотреть использование макроса в vim
или emacs
. Если бы Вы действительно хотите написать сценарий его, я изучил бы sed
:
Sed является потоковым редактором. Потоковый редактор используется для выполнения основных текстовых преобразований на входном потоке (файл или вход от конвейера).
Снова, точный способ сделать это, будет зависеть от Вашей ситуации, но добавить строку после строки, запускающейся с ШАБЛОНА, можно сделать это:
sed -e 's/\(^PATTERN.*\)/\1\nTextToAdd/' file.old > file.new
Для добавления строки перед строкой, запускающейся с ШАБЛОНА, Вы могли сделать что-то вроде этого:
sed -e 's/\(^PATTERN.*\)/TextToAdd\n\1/' file.old > file.new
Удалить строку, запускающуюся с ШАБЛОНА
sed -e 's/\(^PATTERN.*\)//' file.old > file.new
Прием должен будет найти корректный ШАБЛОН, который поймает только строки, которые Вы хотите.
Можно объединить их путем выполнения soemthing как это:
sed -e 's/\(^PATTERN1.*\)/\1\nTextToAdd/' -e 's/\(^PATTERN2.*\)/TextToAdd\n\1/' file.old > file.new
CLASS
и END
мы могли использовать sed -n -e '/^CLASS$/,/^END$/p' file.txt
, но поскольку sed является потоковым редактором, мы получаем блоки в частях - каждое слово является другой частью, таким образом, мы должны remeber все после CLASS
и прежде END
и затем вставьте его в файл. Я думаю тот инструмент лучше, чем sed
в этом случае будет awk
, но поскольку я не знаю это, я потратил один и полчаса, пытаясь записать некоторый полезный awk сценарий, и я привел к сбою... ;)
– pbm
16.11.2010, 20:55
И решение Python от меня:
file = open('a.txt', 'r')
arr = []
tmp = []
remember = False
for line in file:
if "CLASS" in line:
remember = True # start storing lines
tmp.append(line) # we're storing lines in list
continue # go to next line
if "END" in line:
tmp.append(line) # store line
remember = False # stop storing lines
arr.append(tmp) # add line to list
tmp = [] # clear temp list
continue # go to next line
if remember:
tmp.append(line) # add to list line between CLASS and END
file.close()
file = open('a.txt', 'a')
for tmp in arr:
if ' ...some stuff ...1\n' in tmp: # we can skip
continue # whole block if we find this
for i in tmp:
if "333" in i: # we can skip only one line
continue
file.write(i)
file.close()
Я думаю, что является самым легким понять и изменить, чем awk версия (если Вы не знаете awk)... Btw awk является следующим языком в моем списке языков, которые я хочу выучить... ;)