Проанализируйте текстовый файл на основе определенного разделителя, а затем преобразуйте его в файл CSV.

Если я правильно вас понял, вы ищете что-то вроде:

echo "test line" > file;
for i in {1..21}; do echo "test line" >> file; done

В результате будет создан файл с 22 повторениями «тестовой строки». Если вам нужен файл определенного размера, вы можете использовать что-то вроде этого (в Linux). 1024 - это один килобайт:

while [ $(stat -c "%s" file) -le 1024 ]; do echo "test line" >> file; done

Лично, когда я хочу создать большой файл, я использую два файла и переключаю один в другой. Вы можете повторять процесс до тех пор, пока не достигнете желаемого размера (здесь 1 МБ):

echo "test line" > file;
while [ $(stat -c "%s" file) -le 1048576 ]; do 
    cat file >> newfile
    cat newfile >> file
done

Обратите внимание, что это решение часто превышает желаемый размер, потому что, если размер файла меньше лимита, все будет снова в нем.

Наконец, если все, что вам нужно, это файл желаемого размера и он не должен содержать что-либо, вы можете использовать truncate :

truncate -s 1M file
4
18.07.2016, 22:28
4 ответа

Вот решение Perl:

$ perl -F= -lae '$F[1]=~s/[^0-9]//g; push @h,$F[0]; push @l,$F[1]; 
                  END{print join ",",@h; print join ",",@l}' OpenSimStats.txt 
TestreportsRootAgentCount,TestreportsChildAgentCount,TestreportsGCReportedMemory,TestreportsTotalObjectsCount,TestreportsTotalPhysicsFrameTime,TestreportsPhysicsUpdateFrameTime,TestreportsPrivateWorkingSetMemory,TestreportsTotalThreads,TestreportsTotalFrameTime,TestreportsTotalEventFrameTime,TestreportsLandFrameTime,TestreportsLastCompletedFrameAt,TestreportsTimeDilationMonitor,TestreportsSimFPSMonitor,TestreportsPhysicsFPSMonitor,TestreportsAgentUpdatesPerSecondMonitor,TestreportsActiveObjectCountMonitor,TestreportsActiveScriptsMonitor,TestreportsScriptEventsPerSecondMonitor,TestreportsInPacketsPerSecondMonitor,TestreportsOutPacketsPerSecondMonitor,TestreportsUnackedBytesMonitor,TestreportsPendingDownloadsMonitor,TestreportsPendingUploadsMonitor,TestreportsTotalFrameTimeMonitor,TestreportsNetFrameTimeMonitor,TestreportsPhysicsFrameTimeMonitor,TestreportsSimulationFrameTimeMonitor,TestreportsAgentFrameTimeMonitor,TestreportsImagesFrameTimeMonitor,TestreportsSpareFrameTimeMonitor,TestreportsLastReportedObjectUpdates,TestreportsSlowFrames
0,0,10,0,0,0,2144,0,89,0,0,25,1,553333320617676,554766654968262,0,0,0,0,0,0,0,0,0,1818239402771,0,00106373848393559,017440040409565,0,0,181818199157715,0,1

Флаг -a заставляет perl действовать как awk и разделять каждую строку ввода по разделителю полей, заданному -F (здесь = ) в массив @F . -l добавляет \ n к каждому вызову print , а -e - это сценарий, который будет запускаться в каждой строке.

  • $ F [1] = ~ s / [^ 0-9] // g; : удалите все нечисловые символы из 2-го поля (массивы начинают отсчет с 0, поэтому $ F [1 ] - второе поле).
  • push @ h, $ F [0]; push @ l, $ F [1]; : вставьте первое поле в массив @h , а второе (теперь, когда нецифровые символы удалены) в массив @ l .
  • END {} : выполняется один раз после обработки всего входного файла.
  • print join ",", @ h; : соедините массив @h с , и распечатайте его.
  • print join ",", @ l : как указано выше, но для @l .
3
27.01.2020, 20:44

awk , чтобы помочь вам:

awk -F= '{a[NR,1]=$1;a[NR,2]=$2}
         END{
            for(i=1; i<NR; i++){
                printf a[i,1] ","
            }
            print a[i,1]; 
            for(i=1; i<NR; i++){
                printf "%s", a[i,2]+0
            } 
            print a[i,2];
        }' file

Массив заполняется как ключом $ 1 в первом столбце, так и значением $ 2 во втором столбце.

Когда все строки прочитаны, дважды пройдитесь по всем элементам массивов, чтобы показать как ключ, так и значения.

8
27.01.2020, 20:44

Я знаю, что на этот вопрос был дан ответ, я решил, что просто добавлю свои два цента, как это сделать в (уродливом) однострочном bash

Конечный результат

echo -e $(cut -d"=" -f1 OpenSimStats.txt | tr '\n' ',' | sed 's/,$/\\n/')$(sed -r 's/.*=([0-9]*).*/\1,/g' OpenSimStats.txt | tr -d '\n' | sed 's/,$//')

Это будет в одной строке вывести следующий результат, который вы просили:

TestreportsRootAgentCount,TestreportsChildAgentCount,TestreportsGCReportedMemory,TestreportsTotalObjectsCount,TestreportsTotalPhysicsFrameTime,TestreportsPhysicsUpdateFrameTime,TestreportsPrivateWorkingSetMemory,TestreportsTotalThreads,TestreportsTotalFrameTime,TestreportsTotalEventFrameTime,TestreportsLandFrameTime,TestreportsLastCompletedFrameAt,TestreportsTimeDilationMonitor,TestreportsSimFPSMonitor,TestreportsPhysicsFPSMonitor,TestreportsAgentUpdatesPerSecondMonitor,TestreportsActiveObjectCountMonitor,TestreportsActiveScriptsMonitor,TestreportsScriptEventsPerSecondMonitor,TestreportsInPacketsPerSecondMonitor,TestreportsOutPacketsPerSecondMonitor,TestreportsUnackedBytesMonitor,TestreportsPendingDownloadsMonitor,TestreportsPendingUploadsMonitor,TestreportsTotalFrameTimeMonitor,TestreportsNetFrameTimeMonitor,TestreportsPhysicsFrameTimeMonitor,TestreportsSimulationFrameTimeMonitor,TestreportsAgentFrameTimeMonitor,TestreportsImagesFrameTimeMonitor,TestreportsSpareFrameTimeMonitor,TestreportsLastReportedObjectUpdates,TestreportsSlowFrames
0,0,10,0,0,0,2144,0,89,0,0,25,1,55,55,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,18,0,1

Разбивка кода

Вот подробное описание того, что происходит.

Outer Echo

echo -e $()$()

Отображает результаты двух вложенных команд, которые выполняются первыми, -e означает, что напечатанное \ n переводится в окончательный результат в символы новой строки.

Первая команда

cut -d"=" -f1 OpenSimStats.txt | tr '\n' ',' | sed 's/,$/\\n/'

Первая вложенная команда. Используйте = в качестве разделителя, чтобы извлечь весь текст в виде столбца (серия значений, разделенных \ n ). Замените все \ n на , , затем снова замените последнюю запятую на \ n (в противном случае за последним значением будет стоять запятая).

Эта команда сама по себе дает следующий результат:

TestreportsRootAgentCount,TestreportsChildAgentCount,TestreportsGCReportedMemory,TestreportsTotalObjectsCount,TestreportsTotalPhysicsFrameTime,TestreportsPhysicsUpdateFrameTime,TestreportsPrivateWorkingSetMemory,TestreportsTotalThreads,TestreportsTotalFrameTime,TestreportsTotalEventFrameTime,TestreportsLandFrameTime,TestreportsLastCompletedFrameAt,TestreportsTimeDilationMonitor,TestreportsSimFPSMonitor,TestreportsPhysicsFPSMonitor,TestreportsAgentUpdatesPerSecondMonitor,TestreportsActiveObjectCountMonitor,TestreportsActiveScriptsMonitor,TestreportsScriptEventsPerSecondMonitor,TestreportsInPacketsPerSecondMonitor,TestreportsOutPacketsPerSecondMonitor,TestreportsUnackedBytesMonitor,TestreportsPendingDownloadsMonitor,TestreportsPendingUploadsMonitor,TestreportsTotalFrameTimeMonitor,TestreportsNetFrameTimeMonitor,TestreportsPhysicsFrameTimeMonitor,TestreportsSimulationFrameTimeMonitor,TestreportsAgentFrameTimeMonitor,TestreportsImagesFrameTimeMonitor,TestreportsSpareFrameTimeMonitor,TestreportsLastReportedObjectUpdates,TestreportsSlowFrames

Вторая команда

sed -r 's/.*=([0-9]*).*/\1,/g' OpenSimStats.txt | tr -d '\n' | sed 's/,$//'

Вторая вложенная команда.Удалите весь текст, окружающий желаемое число в каждой строке, в результате появится столбец чисел (значения, разделенные \ n ). Замените все \ n на , , затем удалите запятую в конце.

Это дает следующий результат:

0,0,10,0,0,0,2144,0,89,0,0,25,1,55,55,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,18,0,1

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

1
27.01.2020, 20:44

9 путей к просветлению OpenSim:

С sed и некоторой магией оболочки:

sed 's/=.*//' OpenSimStats.txt | paste -sd, >out.csv
sed 's/.*=//; s/[^0-9]*$//' OpenSimStats.txt | paste -sd, >>out.csv

С sed , без магии оболочки:

sed -n 's/=.*//; 1{ h; b; }; $! H; $ { x; s/\n/,/g; p; }' OpenSimStats.txt >out.csv
sed -n 's/.*=//; 1{ s/[0-9]*$//; h; b; }; s/[^0-9]*$//; $! H; $ { x; s/\n/,/g; p; }' OpenSimStats.txt >>out.csv

С магией оболочки и крошечный кусочек sed :

paste -sd, <(cut -d= -f1 OpenSimStats.txt) <(cut -d= -f2 OpenSimStats.txt | sed 's/[^0-9]*$//')

С cut и некоторой магией оболочки:

cut -d= -f1 OpenSimStats.txt | paste -sd, >out.csv
cut -d= -f2 OpenSimStats.txt | sed 's/[^0-9]*$//' | paste -sd, >>out.csv

С GNU datamash :

sed 's/=/,/; s/[^0-9]*$//' OpenSimStats.txt | datamash -t, transpose

С perl ]:

perl -lnE 's/\D+$//o;
    ($a, $b) = split /=/;
    push @a, $a; push @b, $b;
    END { $, = ","; say @a; say @b }' OpenSimStats.txt

С grep :

grep -o '^[^=]*' OpenSimStats.txt | paste -sd, >out.csv
egrep -o '[0-9.]+' OpenSimStats.txt | paste -sd, >>out.csv

С bash :

#! /usr/bin/env bash
line1=()
line2=()
while IFS='=' read -r a b; do
    line1+=("$a")
    [[ $b =~ ^[0-9.]+ ]]
    line2+=("$BASH_REMATCH")
done <OpenSimStats.txt
( set "${line1[@]}"; IFS=,; echo "$*" ) >out.csv
( set "${line2[@]}"; IFS=,; echo "$*" ) >>out.csv

С awk :

awk -F= '
    NR==1 { a = $1; sub(/[^0-9]+$/, "", $2); b = $2; next }
    { a = a "," $1; sub(/[^0-9]+$/, "", $2); b = b "," $2 }
    END { print a; print b }' OpenSimStats.txt

Дополнительный 10-й путь для ботаников с данными, с csvtk :

csvtk replace -d= -f 2 -p '\D+$' -r '' <OpenSimStats.txt | csvtk transpose

Бонусный 11-й путь с vim :

:%s/\D*$//
:%s/=/\r/
qaq
:g/^\D/y A | normal dd
:1,$-1 s/\n/,/
"aP
:2,$-2 s/\n/,/
:d 1
:w out.csv
9
27.01.2020, 20:44

Теги

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