如何处理 x 列文本文件以获取 y 列?

Jus*_*ner 17 awk text-processing

我有一个文本文件:

a   aa  aaa     b   bb  bbb     c   cc  ccc
d   dd  ddd     e   ee  eee     f   ff  fff
g   gg  ggg     h   hh  hhh     i   ii  iii
j   jj  jjj
Run Code Online (Sandbox Code Playgroud)

我如何处理它并获得这样的 2 列文件:

a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj
Run Code Online (Sandbox Code Playgroud)

或者像这样的三列文件:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jj
Run Code Online (Sandbox Code Playgroud)

我更喜欢获得 awk 解决方案,但也欢迎其他解决方案。

Tho*_*hor 20

将每个字段放在一行上并进行柱状化。

每个字段在一行

tr

tr -s ' ' '\n' < infile
Run Code Online (Sandbox Code Playgroud)

格雷普

grep -o '[[:alnum:]]*' infile
Run Code Online (Sandbox Code Playgroud)

sed

sed 's/\s\+/\n/g' infile
Run Code Online (Sandbox Code Playgroud)

或更便携:

sed 's/\s\+/\
/g' infile
Run Code Online (Sandbox Code Playgroud)

awk

awk '$1=$1' OFS='\n' infile
Run Code Online (Sandbox Code Playgroud)

或者

awk -v OFS='\n' '$1=$1' infile
Run Code Online (Sandbox Code Playgroud)

柱状

粘贴

对于 2 列:

... | paste - -
Run Code Online (Sandbox Code Playgroud)

对于 3 列:

... | paste - - -
Run Code Online (Sandbox Code Playgroud)

等等。

sed

对于 2 列:

... | sed 'N; s/\n/\t/g'
Run Code Online (Sandbox Code Playgroud)

对于 3 列:

... | sed 'N; N; s/\n/\t/g'
Run Code Online (Sandbox Code Playgroud)

等等。

参数

... | xargs -n number-of-desired-columns
Run Code Online (Sandbox Code Playgroud)

xargs用于/bin/echo打印时,请注意看起来像选项的数据echo将被解释为这样。

awk

... | awk '{ printf "%s", $0 (NR%n==0?ORS:OFS) }' n=number-of-desired-columns OFS='\t'
Run Code Online (Sandbox Code Playgroud)

公关

... | pr -at -number-of-desired-columns
Run Code Online (Sandbox Code Playgroud)

或者

... | pr -at -s$'\t' -number-of-desired-columns
Run Code Online (Sandbox Code Playgroud)

列(来自 autogen 包)

... | columns -c number-of-desired-columns
Run Code Online (Sandbox Code Playgroud)

典型输出:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
Run Code Online (Sandbox Code Playgroud)

  • 灌篮高手。+1 先生 (2认同)

Eri*_*ouf 9

正如通配符指出的那样,这只有在您的文件格式良好时才有效,因为没有任何特殊字符被 shell 解释为 globs,并且您对默认的分词规则感到满意。如果对您的文件是否会“通过”该测试有任何疑问,请不要使用这种方法。

一种可能性是printf用来做它喜欢

printf '%s\t%s\n' $(cat your_file)
Run Code Online (Sandbox Code Playgroud)

这将对内容进行分词your_file,并将它们配对并在它们之间使用制表符打印它们。您可以在 中使用更多%s格式字符串printf以获得额外的列。


Sun*_*eep 9

$ sed -E 's/\s+/\n/g' ip.txt | paste - -
a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

$ sed -E 's/\s+/\n/g' ip.txt | paste - - -
a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
Run Code Online (Sandbox Code Playgroud)