2017-01-07 2 views
0

У меня есть большой текстовый файл с некоторыми данными в нем, который выглядит следующим образом:

$ 10c20 
data 
data 
. 
. 
data 
data 
$ 10c21 
data 
data 
. 
. 
data 
data 
$ 10c22 
. 
. 

Я хочу, чтобы извлечь данные между каждыми двумя комментировал линиями (начинается с «$») и сохраните этот фрагмент данных в новом файле, а затем следующий фрагмент до конца файла. Я попробовал «sed», но я не смог получить то, что мне было нужно. Есть идеи?

желаемый результат:

$ 10c20 
    data 
    data 
    . 
    . 
    data 
    data 

и

$ 10c21 
    data 
    data 
    . 
    . 
    data 
    data 

и

$ 10c22 
    data 
    data 
    . 
    . 
    data 
    data 

и ...

+0

Это сложно/невозможно использовать sed для многострочных операций. Не более двух строк подряд - это то, что мне «легко» удается работать. Существует ли какой-либо язык? – kabanus

+1

Пожалуйста, добавьте желаемый результат для ввода этого образца на свой вопрос. – Cyrus

+0

@kabanus Я уже сделал что-то подобное только с двумя строками с разными шаблонами, но я не знаю, как это сделать – gnome

ответ

1

Если вы не хотите 'высокий' язык как Python/Perl есть общий встроенный csplit, хотя вы должны согласиться работать с файлами:

/home/.../RGS/tmp>csplit bla '/^\$/' {*} 
0 
21 
21 
21 
21 
/home/.../RGS/tmp>cat xx00 
/home/.../RGS/tmp>cat xx01 
$ 10c20 
data1 
data1 
/home/.../RGS/tmp>cat xx02 
$ 10c21 
data2 
data2 
/home/.../RGS/tmp>cat xx03 
$ 10c22 
data3 
data3 
/home/.../RGS/tmp>cat xx04 
$ 10c23 
data4 
data4 
/home/.../RGS/tmp> 

где бла это:

$ 10c20 
data1 
data1 
$ 10c21 
data2 
data2 
$ 10c22 
data3 
data3 
$ 10c23 
data4 
data4 

и в конце концов просто rm xx*.

EDIT

После того как файлы будут готовы, в Баш всего:

for inp in xx*; do 
    cat $inp | toSomeComputations & 
    #Or 
    toSomeComputations $inp & 
done 

конечно, вы можете использовать что-то еще, чтобы сделать эту петлю параллельно.

+0

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

+0

Это работает с «переменными и огромными» данными, но, возможно, вам все равно придется использовать скрипт на более легком языке. Если вы не знаете, как обрабатывать файлы после разделения, я отредактирую. – kabanus

+0

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

0

Здесь GNU awk script, который воспроизводит ответ @kabanus. Я не знаю, как это поможет вам, когда ответ @kabanus не работает для вас, но вот он.

script.awk

function doit(header) { 
    # filename with leading zeros in number 
    outFileName = sprintf("out_%04d", NR-1) 
    printf("%s%s", header, $0) > outFileName 
    # now lets run a command on that file, e.g. cat 
    system("cat " outFileName) 
} 

# set record split by the dollar lines 
BEGIN { RS="[$][^\n]+" } 

{ 
    # on NR == 1 (the first record) oldRT is empty 
    # we need to store RT and use oldRT when we output $0 
    # for the next record 
    if(oldRT) doit(oldRT) 
    oldRT = RT 
} 

Выполнить это так: awk -f script.awk yourfile

+0

как я могу распечатать каждый извлеченный фрагмент данных для разделения файлов? (учитывая цикл) – gnome

+0

@ Lars-Fisher ??? – gnome

+0

Момент, пожалуйста, я был далеко от клавиатуры. –

0

Все, что вам нужно:

awk ' 
function doCalculation() { 
    # do whatever you want with the multi-line string "buf" then 
    printf "%s", buf 
    buf = "" 
} 
/^\$/ { doCalculation() } 
{ buf = buf $0 ORS } 
END { doCalculation() } 
' file 

Вы можете сделать ЬиЕ массив вместо многострочно если это более удобно, но логики одинаковы в любом случае.

Смежные вопросы