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

Вы могли использовать сингл sed управляйте как в следующем:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")
2
16.11.2010, 16:28
4 ответа

Естественные инструменты для этого являются awk и Perl (предполагающий, что Вы хотите написать сценарий: для некогда прочь, естественный инструмент является интерактивным редактором). Вот awk сценарий, который копирует все CLASSEND блоки (никакая балансировка не поддерживала: каждый 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'
2
27.01.2020, 21:53

Ну, можно написать сценарий чего-либо.

Однако, если бы я делал это, то я использовал бы 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 для того, как выполнить макрос для каждой строки. Смешивание и подгонка :)

3
27.01.2020, 21:53

Точный инструмент для использования будет зависеть от специфических особенностей задания. Если задание только собирается произойти однажды, Вы могли бы рассмотреть использование макроса в 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
1
27.01.2020, 21:53
  • 1
    Найти только блоки beetwen CLASS и END мы могли использовать sed -n -e '/^CLASS$/,/^END$/p' file.txt, но поскольку sed является потоковым редактором, мы получаем блоки в частях - каждое слово является другой частью, таким образом, мы должны remeber все после CLASS и прежде END и затем вставьте его в файл. Я думаю тот инструмент лучше, чем sed в этом случае будет awk, но поскольку я не знаю это, я потратил один и полчаса, пытаясь записать некоторый полезный awk сценарий, и я привел к сбою... ;) –  pbm 16.11.2010, 20:55
  • 2
    Абсолютно правильный, я не читал, это подробно расспрашивает достаточно перед исчерпыванием ответа. –  Steven D 16.11.2010, 22:50

И решение 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 является следующим языком в моем списке языков, которые я хочу выучить... ;)

1
27.01.2020, 21:53

Теги

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