2015-08-04 2 views
1

У меня есть файл, содержащие следующие строки:Split файла по добывающим линиям между двумя ключевыми словами

string 
string 
string 
MODEL 1 
. 
. 
. 
TER 
string 
string 
string 
MODEL 2 
. 
. 
. 
TER 

где есть 5000 таких MODEL s. Я хочу разбить этот файл таким образом, чтобы каждый раздел, начинающийся MODEL X и заканчивающийся TER (показано точками), сохраняется в собственном файле, а все остальное отбрасывается. Как я могу это сделать? Возможно с awk или split?

Я проверил несколько других подобных вопросов, но не смог применить ответы на свой вопрос.

Также обратите внимание, что я использую Mac OS X.

+0

См http://stackoverflow.com/q/23934486/258523 для обсуждения способов сделать это в 'awk'. –

ответ

2

Вы можете использовать эту AWK для этого:

awk '/^MODEL/{file="model" $2} file{print > file} /^TER/{close(file); file=""}' file 

Как это работает:

/^MODEL/    # match lines starting with MODEL 
file="model" $2  # make variable file as model + model_no from column 2 
file{...}    # execute of file variable is set 
{print>file}   # print each record to file 
/^TER/     # match lines starting with TER 
{close(file); file=""} # close file and reset file to "" 

Затем проверьте, как:

cat model1 
MODEL 1 
. 
. 
. 
TER 

cat model2 
MODEL 2 
. 
. 
. 
TER 
+0

Работает до 18-го файла, после чего он заканчивается ошибкой: 'awk: model18 делает слишком много открытых файлов'. Он также печатает строки 'string' после' TER'. – sodiumnitrate

+0

ах я пропустил 'close'. Попробуйте обновить код сейчас. – anubhava

+0

Спасибо за ответ, теперь он отлично работает. Не могли бы вы, пожалуйста, объяснить команду немного для меня, чтобы понять, как это работает? – sodiumnitrate

1

Это работает даже с dash:

go=false text= model_ID= 
while IFS= read line; do 
    if [ "`printf "$line" | grep '^MODEL'`" ]; then 
     model_ID="`printf "$line" | sed -e 's/^MODEL //'`" 
     go=true 
    elif [ "`printf "$line" | grep '^TER'`" ]; then 
     printf "$text" > "MODEL_$model_ID" 
     text="" 
     model_ID="" 
     go=false 
    else 
     $go && text="$text$line\n" 
    fi 
done 
Смежные вопросы