Bash код для выбора нескольких столбцов из переменной - PullRequest
1 голос
/ 28 февраля 2020

В файле хранится список координат (см. Рисунок слева). Оттуда я хочу скопировать только координаты (отмечены красным) и поместить их в другой файл.

Я копирую правильный раздел из файла, используя COORD=`grep -B${i} '&END COORD' ${cpki_file}. Затем я попытался использовать awk для извлечения необходимых чисел из переменной COORD. Он выводит все числа в файле, но удаляет пробелы между значениями (рисунок справа).

Как записать отмеченный красным раздел как есть?

enter image description here

N=200
NEndCoord=`grep -B${N} '&END COORD' ${cpki_file}|wc -l`
NCoord=`grep -B${N} '&END COORD' ${cpki_file}| grep -B200  '&COORD' |wc -l`
let i=$NEndCoord-$NCoord

COORD=`grep -B${i} '&END COORD' ${cpki_file}`

echo "$COORD" | awk '{ print $2 $3  $4 }'
echo "$COORD" | awk '{ print $2 $3  $4 }'>tmp.txt

Ответы [ 2 ]

2 голосов
/ 28 февраля 2020

Когда вы начнете использовать комбинации grep, sed, awk, cut и т. Д., Вы должны понимать, что все это можно сделать одной командой awk. В случае OP это будет происходить точно так же:

awk '/[&]END COORD/{p=0}
     p { print $2,$3,$4 }
     /[&]COORD/{p=1}' file

Это анализирует файл, отслеживающий флаг печати p. Флаг устанавливается, если "& COORD" найден, и не установлен, если "& END COORD" найден. Печать выполняется только при установленном флаге p. Так как мы не хотим печатать строку с «& END COORD», мы должны сбросить флаг, прежде чем мы сделаем проверку на печать. То же самое относится и к строке с «& COORD», но там мы должны сбросить ее после того, как выполним проверку печати (это немного странная обратная логика c).

Проблема с вышеупомянутым является то, что он также будет обрабатывать строки


UNIT angstrom

Если вы хотите удалить их, вы можете проверить общие столбцы:

awk '/[&]END COORD/{p=0}
     p && (NF==4){ print $2,$3,$4 }
     /[&]COORD/{p=1}' file

Из печати только строки, которые не содержат «UNIT» или являются пустыми:

awk '/[&]END COORD/{p=0}
     p && (NF>0) && ($1 != "UNIT"){ print $2,$3,$4 }
     /[&]COORD/{p=1}' file
0 голосов
/ 28 февраля 2020

sed однострочный:

sed -n '/^&COORD$/,/^UNIT/{s/.*[[:space:]]\+\(.*\)[[:space:]]\+\(.*\)[[:space:]]\+\(.*\)/\1\t\2\t\3/p}' <infile.txt >outfile.txt

Объяснение:

Вызов:

  • sed: редактор потоков
    • -n: не печатать, если не явное

Команды в sed:

  • /^&COORD$/,/^UNIT/: выбор групп строк после &COORDS и до UNIT.
  • {s/.*[[:space:]]\+\(.*\)[[:space:]]\+\(.*\)[[:space:]]\+\(.*\)/\1\t\2\t\3/p}: обработка каждой выбранной строки.
    • s/.*[[:space:]]\+\(.*\)[[:space:]]\+\(.*\)[[:space:]]\+\(.*\): Regex захватывает группы, разделенные пробелом, кроме первой.
    • /\1\t\2\t\3/: заменяет значения захваченных групп табуляцией.
    • p: явный распечатка.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...