2012-04-03 41 views
4

我需要如何改變格式化文件按以下方式 文件1建議的格式:的Perl,sed或awk的一個班輪更改文件的

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}'. 

但我想知道是否有更有效的方法或者已經知道做這項工作的做法。

+2

非常感謝你墊。我最近加入了社區。我會這麼做 – Alby 2012-04-03 18:09:03

回答

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

中查找選項perlrun

另一個有用的添加是-l(追加換行打印),但在這種情況下不能。

+0

非常好。任何一個使用@F的班輪在我的書中都很酷:) – 2012-04-03 21:57:10

+0

@briandfoy - 謝謝 - 但它實際上只是一個班輪。請放心,我確實閱讀了[你的書](http://amzn.com/0321496949)! :)我可以高度推薦它! – Lumi 2012-04-03 22:31:13

+0

謝謝你的回答!順便說一下,是真正需要的「<」嗎?我沒有嘗試過,它仍然有效。它有什麼作用?我只熟悉>用於指導輸出。 – Alby 2012-04-04 16:14:55

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

,或者替換地

awk '{num=$2;getline;print num,$2}' file 
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 
1

這將與任何標題文本工作,不只是固定一個 >>

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

假設你的輸入文件製表符分隔:

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

應該是相當快的,因爲這正是cutpaste被寫做。

+0

+1 - 'paste'和'join'從來沒有真正成爲我永久的心智工具集,但這可能是最具機器效率的解決方案。空格分隔文件的變體:'cut -b8-/tmp/ab |粘貼 - ' – Lumi 2012-04-03 22:47:16

+0

哇...這是非常優雅。你能解釋一下 - - 選項在粘貼命令中做了什麼? cygwin手冊頁似乎並不明確。而且它是否靈活?意思是我可以給更多的選項,比如粘貼(轉置)下面的2行? – Alby 2012-04-04 16:19:18

+1

請參閱http://man.cx/paste - 'paste'將文件名作爲參數並連接相應的行。如果「 - 」以文件名的形式給出,則從stdin讀取該文件的行。由於在該命令中有2個破折號,所以一行將被讀取爲「文件1」並且另一行將被讀取爲「文件2」,直到所有輸入被消耗。 – 2012-04-04 16:42:19

0

這可能會爲你工作:

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