Perl, sed или awk one-liner для изменения формата файла - PullRequest
4 голосов
/ 03 апреля 2012

Мне нужен совет, как изменить файл, отформатированный следующим образом file1:

A       504688
B       jobnameA
A       504690
B       jobnameB
A       504691
B       jobnameC
...

в файл2:

A       B
504688  jobnameA
504690  jobnameB
504691  jobnameC
...

Я мог бы придумать одно решение:

cat file1 | perl -0777 -p -e 's/\s+B/\t/' | awk '{print $2"\t"$3}'.

Но мне интересно, есть ли более эффективный способ или уже известная практика, которая делает эту работу.

Ответы [ 6 ]

7 голосов
/ 03 апреля 2012
 perl -nawe 'print "@F[1 .. $#F]", $F[0] eq "A" ? "\t" : "\n"' < /tmp/ab

Поиск параметров в perlrun.

Еще один полезный вариант для добавления - -l (добавить новую строку для печати), но не в этом случае.

5 голосов
/ 03 апреля 2012

Если ваш входной файл разделен табуляцией:

echo $'A\tB'
cut -f2 filename | paste - -

Должно быть довольно быстро, потому что это именно то, для чего были написаны cut и paste .

2 голосов
/ 03 апреля 2012
awk '/^A/{num=$2}/^B/{print num,$2}' file

Или, альтернативно,

awk '{num=$2;getline;print num,$2}' file
1 голос
/ 03 апреля 2012

Это будет работать с любым текстом заголовка, а не только с фиксированным A и B >>

awk '{a=$1;b=$2;getline;if(c!=1){print a,$1;c=1};print b,$2}' file1 >file2

... и будет печатать также строка заголовка

Если вам нужен разделитель \t, используйте:

awk '{a=$1;b=$2;getline;if(c!=1){print a"\t"$1;c=1};print b"\t"$2}' file1 >file2
1 голос
/ 03 апреля 2012

Вот решение sed:

sed -e 'N' -e 's/A\s*\(.*\)\nB\s*\(.*\)/\1\t\2/' file

Эта версия также напечатает верхний колонтитул:

sed '1{h;s/.*/A\tB/p;g};N;s/A\s*\(.*\)\nB\s*\(.*\)/\1\t\2/' file

Или альтернатива:

sed -n '/^A\s*/{s///;h};/^B\s*/{s///;H;g;s/\n/\t/p}' file

Если ваш sed не поддерживает точки с запятой в качестве разделителя команд для альтернативы:

sed -n '
/^A\s*/{       # if the line starts with "A"
s///             # remove the "A" and the whitespace
h                # copy the remainder into the hold space
}              # end if
/^B\s*/{       # if the line starts with "B"
s///             # remove the "B" and the whitespace 
H                # append pattern space to hold space
g                # copy hold space to pattern space
s/\n/\t/p        # replace newline with tab and print
}' file

Эта версия также будет печатать заголовок вверху:

sed -n '/^A\s*/{s///;h;1s/.*/A\tB/p};/^B\s*/{s///;H;g;s/\n/\t/p}' file
0 голосов
/ 04 апреля 2012

Это может работать для вас:

 sed -e '1i\A\tB' -e 'N;s/A\s*\(\S*\).*\nB\s*\(\S*\).*/\1\t\2/' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...