Дайте мне знать, если это то, что вам нужно.
labels.txt
, используемый для тестирования:label_zero
label_one
label_two
label_three
label_four
echo "1 1 0 0 2 3 23101 23101 0 0 2 0 5 2 0 0" |
perl -e 'open($lf, "<", "labels.txt");
@lbs = <$lf>;
chomp(@lbs);
@cols = split(/ /, <STDIN>);
for $i (0..$#cols) {
printf("%s %s\n", $lbs[$i] || "label_".$i, $cols[$i])
};'
label_zero 1
label_one 1
label_two 0
label_three 0
label_four 2
label_5 3
label_6 23101
label_7 23101
label_8 0
label_9 0
label_10 2
label_11 0
label_12 5
label_13 2
label_14 0
label_15 0
Очевидно, вы хотите удалить из ввода все строки комментариев, за которыми следуют другие строки комментариев. Вызов sed
терпит неудачу, потому что регулярные выражения по умолчанию "жадные" (, т.е. потребляют как можно больше ), что не может быть легко изменено.
Поэтому я добавлю основанное наawk
-решение к заявленной цели:
awk '/^#/{buf=$0;next} {if (buf) {print buf; buf=""}}1' "${InputP}"
или чуть более компактный:
awk '/^#/{buf=$0;next} buf{print buf; buf=""}1' "${InputP}"
1
за пределами блоков правил означает «печатать текущую строку, включая все изменения, сделанные до сих пор» -, что в данном случае отсутствует ). ]. /^#/
), содержимое будет сохранено в буфере buf
, но еще не напечатано. Команда next
пропускает выполнение до следующей строки, поэтому оставшийся код применяется только к строкам комментариев, отличным от -. Проблема в том, что .*
является жадным, поэтому sed -z -e 's/#.*\n#/#/g'
будет соответствовать от самой первой строки, содержащей #
, до последней строки, начинающейся с #
. Это происходит только из-за флага -z
, который одновременно поглощает весь файл в пространстве шаблонов (, предполагая, что в текстовом файле нет нулевых байтов ).
Сценарий Sed для решения вашей проблемы:
sed -n '/^#/N;/\n#/D;p' file
/^#/N
Если строка начинается с #
, добавьте следующую строку в пространство шаблонов. /\n#/D
Если пространство шаблонов содержит новую строку, за которой следует #
, удалите все до новой строки и начните новый цикл. p
Печать пространства шаблона при достижении этой команды. Это должно работать:
perl -ne 'print $x,$_ unless /^#/; $x = /^#/ ? $_ : ""' < infile
Я получил ожидаемый результат, который вы опубликовали.
Редактировать :объяснение
$x
за $left_over_line_to_be_printed
, если хотите:-)