Зная файловый дескриптор 27, вы прошли бы /proc
процесс QEMU:
$ ls /proc//fd/27
На том же уровне, что и каталог fd
, находится еще один каталог fdinfo
, содержащий такие детали, как этот:
$ cat /proc//fdinfo/27
pos: 0
flags: 0104002
mnt_id: 18
iff: tap0123acdc-66
Запись iff
в этом файле — это ответвительное устройство.
Простой 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
Это сделает следующая 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
полям плюс один; никаких гарантий не предусмотрено.
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
С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
.