sed: добавьте каждую строку с пробелом - PullRequest
1 голос
/ 10 августа 2009

Я пытаюсь преобразовать большое количество файлов из простого текстового макета в CSV. Первые несколько строк одного из файлов выглядят так:

SLICE AT X= -0.25
   ELEM NO         XI-COORD               INWARD-NORMAL
 1     0     0.000   0.000   0.000     0.000   0.000   0.000
 2     0     0.000   0.000   0.000     0.000   0.000   0.000
 3     0     0.000   0.000   0.000     0.000   0.000   0.000

Число, указанное в первой строке (-0,25), необходимо вставить в качестве параметра в каждую из строк данных. Поскольку это число варьируется в каждом из сотен файлов, я не могу предоставить его как литерал.

Я написал следующую программу sed:

# Reduce line 1 to just a number.
s/SLICE AT X= //
# Store line 1 in hold space.
1h
# Clear the other header line.
2d
# Insert X coordinate from hold space.
/^\ \{1,\}/G
# Separate values with commas.
s/\ \{1,\}/,/g

Достигается настолько, чтобы производить это:

-0.25
,1,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25
,2,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25
,3,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25
,4,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25

Обратите внимание, что первая строка вывода является исходной первой строкой.

Может ли кто-нибудь помочь мне вставить вставленный номер в начало каждой строки?

Заранее спасибо,

Ross

Ответы [ 5 ]

2 голосов
/ 10 августа 2009

Я согласен с Уильямом Перселлом: вы еще не достигли предела возможностей этого инструмента делайте, но вы достигли предела того, что следует делать с этим инструментом.

Во всяком случае, вот другой подход, все еще немного хитрый.


# Reduce line 1 to just a number.
s/SLICE AT X= //
# Store line 1 in hold space.
1h
# Clear the other header line.
1,2d
# Insert X coordinate from hold space.
/^\ \{1,\}/G
# The \n from line 1 tells me where to split/swap
s/\(.*\)\n\(.*\)/\2\1/
# Separate values with commas.
s/ \{1,\}/,/g
1 голос
/ 11 августа 2009

вы можете использовать awk для таких задач. используйте sed только для очень простых задач.

awk '/SLICE AT X/{ num = $NF;print;next}
NR>2{
    $(NF+1) = num     
    $1=$1    
}1' OFS="," file

выход

# more file
SLICE AT X= -0.25
   ELEM NO         XI-COORD               INWARD-NORMAL
 1     0     0.000   0.000   0.000     0.000   0.000   0.000
 2     0     0.000   0.000   0.000     0.000   0.000   0.000
 3     0     0.000   0.000   0.000     0.000   0.000   0.000
# ./shell.sh
SLICE AT X= -0.25
   ELEM NO         XI-COORD               INWARD-NORMAL
1,0,0.000,0.000,0.000,0.000,0.000,0.000,-0.25
2,0,0.000,0.000,0.000,0.000,0.000,0.000,-0.25
3,0,0.000,0.000,0.000,0.000,0.000,0.000,-0.25
1 голос
/ 10 августа 2009

Обратите внимание, что это действительно лучше всего сделать с Perl, но вот решение sed.

#!/usr/bin/sed -f

# Reduce line 1 to just a number.
s/SLICE AT X= //
# Store line 1 in hold space.
1h
# Clear the other header line.
1,2d
# Insert X coordinate from hold space.
x
G
# Separate values with commas.
s/\ \{1,\}/,/g
s/\n//g
p
s/\([^,]*\),.*/\1/
h
d

Проблема в том, что G добавляет пространство удержания, поэтому вам нужно сначала использовать x, чтобы поменять местами образец и пространство удержания, добавить пространство удержания (которое было пространством образца), вывести строку и затем восстановить пространство удержания. На самом деле, sed не подходит для этого ...

1 голос
/ 10 августа 2009

Должно ли это быть sed ? Это делает трюк для меня:

$ perl -lane '$x=$1,next if m/^SLICE AT X= (.+)$/; next if $. == 2; print join "," => ($x, @F)' /tmp/so-1255443
-0.25,1,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25,2,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25,3,0,0.000,0.000,0.000,0.000,0.000,0.000
0 голосов
/ 14 марта 2012

Это может работать для вас:

sed -i '1{s/.* //;h;d};2d;s/\s\+/,/g;G;s/\(.*\)\n\(.*\)/\2\1/' file
-0.25,1,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25,2,0,0.000,0.000,0.000,0.000,0.000,0.000
-0.25,3,0,0.000,0.000,0.000,0.000,0.000,0.000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...