sed:在每个行前面加上保留空间

时间:2009-08-10 15:09:48

标签: regex unix sed

我正在尝试将大量文件从纯文本布局转换为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

请注意,输出的第一行是原始第一行。

有人可以帮我把粘贴的号码放到每行的开头吗?

提前致谢,

罗斯

5 个答案:

答案 0 :(得分:2)

我同意William Pursell的说法:你还没有达到这个工具的极限  但是你已经达到了使用这个工具应该做的限制。

无论如何,这是另一种方法,仍然有点笨拙。


# 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 :(得分:1)

是否必须 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

答案 2 :(得分:1)

请注意,这最好用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不适合这个......

答案 3 :(得分:1)

您可以使用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

答案 4 :(得分:0)

这可能对您有用:

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