2009-08-10 16 views
1

我試圖將大量文​​件從純文本佈局轉換爲CSV。文件中的一個的前幾行是這樣的:需要sed:在保存空間前加上每行

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 

注意輸出的第一行是原來的第一道防線。

任何人都可以幫助我得到粘貼的數字到每一行的開始?

由於提前,

羅斯

回答

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 
+0

感謝, 這確實與所提供的摘錄了偉大的工作,但運行到與多個文件作爲輸入問題。雖然每個文件都使用相同的佈局,但第二行會隱藏到輸出中。我想知道這是否可能是由於絕對的線路位置? – 2009-08-10 15:49:01

+0

$。在使用<>時不會在新文件上重置爲零。請參閱perlfunc文檔中的eof – 2009-08-10 16:13:31

+0

謝謝。我最終只是將perl調用包裝在一個小小的shell腳本中,而這個腳本完成了。感謝您的側面思考。 – 2009-08-11 10:22:42

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不是合適的工具...

2

我同意威廉Pursell:你還沒有達到這個工具可以 做的限制,但你已經達到了應該做什麼的限制這個工具。

無論如何,這是另一種方法,仍然略微kludgey。


# 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

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