Perl,sed或awk one-liner来改变文件的格式

时间:2012-04-03 17:39:35

标签: regex perl unix sed awk

我需要有关如何按照以下方式更改文件的建议 文件1:

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

进入file2:

A       B
504688  jobnameA
504690  jobnameB
504691  jobnameC
...

我能想到的一个解决方案是:

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

但我想知道是否有更有效的方法或已知的做法可以完成这项工作。

6 个答案:

答案 0 :(得分:7)

 perl -nawe 'print "@F[1 .. $#F]", $F[0] eq "A" ? "\t" : "\n"' < /tmp/ab

perlrun中查找选项。

要添加的另一个有用的是-l(在打印时附加换行符),但在这种情况下不会。

答案 1 :(得分:5)

假设您的输入文件是分隔符:

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

应该非常快,因为这正是写cutpaste的目的。

答案 2 :(得分:2)

awk '/^A/{num=$2}/^B/{print num,$2}' file

或者,或者,

awk '{num=$2;getline;print num,$2}' file

答案 3 :(得分:1)

这是一个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

答案 4 :(得分:1)

这适用于任何标题文字,而不仅仅是修复 A B &gt;&gt;

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

答案 5 :(得分:0)

这可能对您有用:

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