2016-05-19 12 views
1

У меня есть файл типа поля поля столбца (где символы 1 - 6 соответствуют field 1, 7 - 11 - field 2 и т. Д.).Sed Pattern Match, который использует смещение номера строки в строке замены?

Основные атрибуты:

  • Каждая строка длиной 80 символов.
  • Текст в field 2 до field 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 

Это отредактирует поле 2 ширины 5 на все большее число.

+0

Отлично, это намного чище. Я ценю помощь. Кроме того, поскольку я забочусь обо втором поле, я могу сократить его до 'awk -v OFS = '' -v FIELDWIDTHS = '6 5 69' '/^HETATM/{$ 2 = sprintf ("% 5d ", ++ count) }; 1 'file.pdb'! –

 Смежные вопросы

  • Нет связанных вопросов^_^