Разделить текстовый файл на части по шаблону, взятому из текстового файла - PullRequest
3 голосов
/ 28 февраля 2012

У меня много текстовых файлов с данными фиксированной ширины, например ::10000

$ head model-q-060.txt 
% x                      y                        
15.0                     0.0                      
15.026087                -1.0                     
15.052174                -2.0                     
15.07826                 -3.0                     
15.104348                -4.0                     
15.130435                -5.0                     
15.156522                -6.0                     
15.182609                -6.9999995               
15.208695                -8.0  

Данные содержат 3 или 4 прогона симуляции, все они хранятся в одном текстовом файле без разделителя между прогонами. Другими словами, нет пустой строки или чего-либо, например если бы было только 3 «записи» за прогон, это выглядело бы так для 3 прогонов:

$ head model-q-060.txt 
% x                      y                        
15.0                     0.0                      
15.026087                -1.0                     
15.052174                -2.0                     
15.0                     0.0                      
15.038486                -1.0                     
15.066712                -2.0                     
15.0                     0.0                      
15.041089                -1.0                     
15.087612                -2.0                     

Это выходной файл COMSOL Multiphysics для тех, кто заинтересован. Визуально вы можете сказать, где начинаются новые данные прогона, поскольку первое значение x повторяется (фактически вся вторая строка может быть одинаковой для всех из них). Поэтому мне нужно сначала открыть файл и получить это значение x, сохранить его, а затем использовать его как шаблон для сопоставления с awk или csplit. Я изо всех сил пытаюсь решить это!

csplit сделает работу:

$ csplit -z -f 'temp' -b '%02d.txt' model-q-060.txt /^15\.0\\s/ {*}

но я должен знать схему, на которую можно разделиться. Этот вопрос похож, но каждый из моих текстовых файлов может иметь различный шаблон для сопоставления: Разделение файлов на основе содержимого файла и сопоставления с шаблоном .

Бен.

Ответы [ 3 ]

3 голосов
/ 28 февраля 2012

Вот простой скрипт awk, который будет делать то, что вы хотите:

BEGIN { fn=0 }
NR==1 { next }
NR==2 { delim=$1 }
$1 == delim {
    f=sprintf("test%02d.txt",fn++);
    print "Creating " f
}

{ print $0 > f }
  1. инициализировать номер выходного файла
  2. игнорировать первую строку
  3. извлечь разделительиз второй строки
  4. для каждой входной строки, первый токен которой соответствует разделителю, установите имя выходного файла
  5. для всех строк, запишите в текущий выходной файл
1 голос
/ 28 февраля 2012

Это должно сделать работу - протестируйте там, где у вас не так много temp*.txt файлов::)

rm -f temp*.txt

cat > f1.txt <<EOF
% x                      y                        
15.0                     0.0                      
15.026087                -1.0                     
15.052174                -2.0                     
15.0                     0.0                      
15.038486                -1.0                     
15.066712                -2.0                     
15.0                     0.0                      
15.041089                -1.0                     
15.087612                -2.0    
EOF

first=`awk 'NR==2{print $1}' f1.txt|sed 's/\\./\\\\./'`
echo --- Splitting by: $first

csplit -z -f temp -b %02d.txt f1.txt /^"$first"\\s/ {*}

for i in temp*.txt; do
  echo ---- $i
  cat $i
done

Вывод выше:

--- Splitting by: 15\.0
51
153
153
136
---- temp00.txt
% x                      y                        
---- temp01.txt
15.0                     0.0                      
15.026087                -1.0                     
15.052174                -2.0                     
---- temp02.txt
15.0                     0.0                      
15.038486                -1.0                     
15.066712                -2.0                     
---- temp03.txt
15.0                     0.0                      
15.041089                -1.0                     
15.087612                -2.0    

Конечно, вы столкнетесь с проблемами, если у вас будет повторяющееся значение второго столбца (15.0 в приведенном выше примере) - решение, которое будет немного сложнее - упражнение, оставленное для читателя ...

0 голосов
/ 28 февраля 2012

Если количество строк в расчете является постоянным, вы можете использовать это:

cat your_file.txt | grep -P "^\d" | \
   split --lines=$(expr \( $(wc -l "your_file.txt" | \
   awk '{print $1'}) - 1 \) / number_of_runs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...