Разделить строки и заменить отсутствующие поля

Зная файловый дескриптор 27, вы прошли бы /procпроцесс QEMU:

 $ ls /proc//fd/27

На том же уровне, что и каталог fd, находится еще один каталог fdinfo, содержащий такие детали, как этот:

$ cat /proc//fdinfo/27
pos:    0
flags:  0104002
mnt_id: 18
iff:    tap0123acdc-66

Запись iffв этом файле — это ответвительное устройство.

Ссылки

0
21.06.2021, 20:29
4 ответа

Простой awkскрипт для вывода пар полей из каждой строки, начиная со 2-го поля, добавляя к каждой выводимой паре префикс 1-го поля в строке.

$ awk -F '|' 'BEGIN { OFS=FS } { for (i = 2; i+1 <= NF; i += 2) print $1, $i, $(i+1) }' file
mercedes|$40000|black
mercedes|$42000|white
mercedes|$41000|red
audi|$31000|blue
audi|$10000|white
mercedes|$5000|blue

Это предполагает, что ввод соответствует ожиданиям, то есть окончательные данные должны быть организованы в три столбца. Это означает, что входные данные должны строго следовать

title|pair 1a|pair 1b|pair 2a|pair 2b|...|pair Na|pair Nb
7
28.07.2021, 11:23

Это сделает следующая awkпрограмма. Вы можете передать желаемое количество полей в строке (в вашем случае 3 )как переменную nfв программу.

awk -v nf=3 'BEGIN{FS=OFS="|"}
             NF==nf {print;next}
             {
                hd=$1;
                for (i=2;i<=NF;i++) {
                  if ((i-2)%(nf-1)==0) {printf "%s%s",hd,OFS}
                  printf "%s%s",$i,((i-1)%(nf-1)==0)?ORS:OFS
                }
             }' file
mercedes|$40000|black
mercedes|$42000|white
mercedes|$41000|red
audi|$31000|blue
audi|$10000|white
mercedes|$5000|blue

Это проверит необходимость разделения строки. Если строка содержит только поля nf, в любом случае(NFявляется встроенным -счетчиком полей для текущей строки ), он печатает его без изменений.

В противном случае:

  • Он сохраняет первое поле в переменнойhd(для «заголовка» ).

  • Затем он выполняет итерацию по всем полям «данных» и добавляет к выходным данным префикс поля hd, за которым следуют поля nf-1из входных данных, а затем все повторяется до тех пор, пока строка не будет обработана.

    Это делается путем проверки того, является ли расстояние между текущим полем iи первым полем «данных» (номер 2 )целым числом nf, и печати только поля hd. тогда. Такая же логика используется для принятия решения о том, следует ли печатать разделитель полей (OFS, установленный в |в начале ), чтобы продолжить строку, или разделитель записей (ORS, по умолчанию новая строка )для начала. новая линия.

Это предполагает, что ваши строки содержат только целое число, кратное nf-1полям плюс один; никаких гарантий не предусмотрено.

3
28.07.2021, 11:23
awk -F'[|]' '{ for(i=3; i<NF; i+=2) sub($i, $i ORS $1) }1' infile

обратите внимание, что первым аргументом функцииsub(regexp, replacement [, target])является регулярное выражение , поэтому $iбудет рассматриваться как регулярное выражение .

см. также дополнительную информацию о ‘\’ и ‘&’ с функциями sub (), gsub ()и gensub (), когда речь идет о втором аргументе этих функций.


Или, как вариант, сделайте следующее, чтобы не возникало вышеуказанных проблем с сабвуфером():

awk 'BEGIN{ FS=OFS="|" } { for(i=3; i<NF; i+=2) $i= $i ORS $1 }1' infile 
3
28.07.2021, 11:23

Сperl:

perl -F"\|" -le '$,="|";
for (my $a=1;$a<@F;$a+=2) 
{print $F[0],$F[$a], $F[$a+1]}' input
  • -F"\|"Разделитель полей ввода установлен на|
  • $,="|";Разделитель полей вывода установлен на|
  • $a<scalar @F;Здесь scalar @Fуказывает общее количество полей и $a<scalar @F, потому что поля в perl начинаются с нуля.

Это ответ @Kusalananda, но в perl.

2
28.07.2021, 11:23

Теги

Похожие вопросы