2016-05-19 46 views
1

我有一個列字段類型的標準的文件(其中字符通過16對應field 17通過11field 2,等等)。在替換字符串中使用行號偏移量的Sed模式匹配?

主要屬性是:

  • 每個線長80字符。
  • field 2field N中的文本總是 right在該領域內是合理的。

我有這樣一個文件:

REMARK 1 
HETATM 1 
HETATM 5 
HETATM 6 
HETATM 7 
HETATM 9 
HETATM 12 
HETATM 15 
HETATM 19 
HETATM 23 
HETATM 27 
HETATM 30 
HETATM 34 
HETATM 38 
END 

對於HETATM記錄...其中前六個數等於該字符串的行...我想在第二場以取代數字(字符7通過11)與條目號,從1開始。

即我所要的輸出表現爲:

REMARK 1 
HETATM 1 
HETATM 2 
HETATM 3 
HETATM 4 
HETATM 5 
HETATM 6 
HETATM 7 
HETATM 8 
HETATM 9 
HETATM 10 
HETATM 11 
HETATM 12 
HETATM 13 
END 

目前我最簡潔的解決方案(使用臨時文件進行測試,以避免搞砸了我原來的)是:

#!/bin/bash 
f=file.pdb 
fTmp=${f}.tmp 
cp $f $fTmp 
for ((l=1; l<$(wc -l $fTmp | awk '{print $1}'); l++)); do 
    sed -i "$((l + 1))"'s#\(HETATM\)[ 0-9]\{5\}#\1'"$(printf '%5s' $l)"'#g' $fTmp 
done 
cat $fTmp 
rm $fTmp 

刪除這個臨時的文件行李變成:

f=file.pdb 
for ((l=1; l<$(wc -l $f | awk '{print $1}'); l++)); do 
    sed -i "$((l + 1))"'s#\(HETATM\)[ 0-9]\{5\}#\1'"$(printf '%5s' $l)"'#g' $f 
done 

好像應該有些辦法t o使用sed中的行號創建一個簡短的解決方案 - 可能是單個sed -i命令。假設這是可能的,唯一的複雜性是需要進行一些算術運算 - 第一條匹配應該設置爲1總是出現在第二條線上。

我希望有一個sed解決方案。我很猶豫使用awk,因爲空格填充很重要,並且需要內聯編輯,所以sed好像是更好的選擇。

請注意,一旦我有一個改進的解決方案,驗證工作,我會拋出*.tmp文件的東西,並直接在目標文件上運行,因此一個sed -i命令可能可以完成這項工作。

回答

1

如果您有GNU awk,您可以指定您的輸入是固定寬度的字段。例如,

awk -v OFS='' -v FIELDWIDTHS='6 5 6 6 6 6 6' ' 
/^HETATM/{ $2 = sprintf("%5d",++count) };1' file.pdb 

這將編輯寬度爲5的字段2以增加數字。

+0

完美這是更清潔。我很感激幫助。另外,因爲我只關心第二個字段,我可以將它縮短爲'awk -v OFS =''-v FIELDWIDTHS ='6 5 69''/^HETATM/{$ 2 = sprintf(「%5d」,++ count) }; 1'file.pdb'! –

相關問題