我使用txt文件(unix,shell脚本)工作,这些文件由管道分隔数百万字段,而不是由\n
或\r
分隔。
像这样的东西:
field1a|field2a|field3a|field4a|field5a|field6a|[...]|field1d|field2d|field3d|field4d|field5d|field6d|[...]|field1m|field2m|field3m|field4m|field5m|field6m|[...]|field1z|field2z|field3z|field4z|field5z|field6z|
所有文字都在同一行。
每个文件的字段数都是固定的。
(在本例中我有field1=name; field2=surname; field3=mobile phone; field4=email; field5=office phone; field6=skype
)
当我需要找到一个字段(ex field2
)时,像grep这样的命令不起作用(在同一行)。
我认为一个好的解决方案可以做一个脚本,用#34; \ n"分隔每6个字段。并做了一个grep。我对吗?非常感谢你!
答案 0 :(得分:3)
使用awk:
$ cat a
field1a|field2a|field3a|field4a|field5a|field6a|field1d|field2d|field3d|field4d|field5d|field6d|field1m|field2m|field3m|field4m|field5m|field6m|field1z|field2z|field3z|field4z|field5z|field6z|
$ awk -F"|" '{for (i=1;i<NF;i=i+6) {for (j=0; j<6; j++) printf $(i+j)"|"; printf "\n"}}' a
field1a|field2a|field3a|field4a|field5a|field6a|
field1d|field2d|field3d|field4d|field5d|field6d|
field1m|field2m|field3m|field4m|field5m|field6m|
field1z|field2z|field3z|field4z|field5z|field6z|
在这里,您可以轻松设置行的长度。
希望这有帮助!
答案 1 :(得分:2)
您可以使用sed
将行分成多行:
sed 's/\(\([^|]*|\)\{6\}\)/\1\n/g' input.txt > output.txt
说明:
我们必须使用(){}
的重反斜杠转义,这会使代码稍微不可读。
但简而言之:
(([^|]*|){6})
和s/
之间的/\1
(为了便于阅读而删除反斜杠)一词将匹配:
[^|]*
任何字符,但“|”,重复多次
|
后跟“|”
上面显然是一列,它与封闭的parantheses (
和)
整个小组重复6次{6}
然后再将其与封闭的parantheses (
和)
组合在一起,形成一整套
该术语的其余部分易于阅读:
将上述(6个字段的整个数据集)替换为\1\n
,/
和/g
之间的部分
\1
是指sed表达式中的“第一个”组(启动的“第一个”组,因此它是6个字段的整个数据集)
\n
是换行符
所以替换6个字段的整个数据集,然后换行换行符
并重复执行此操作(尾随g
)
答案 2 :(得分:2)
您可以使用sed
将每第6个|
转换为换行符。
在我的tcsh版本中,我可以这样做:
sed 's/\(\([^|]\+|\)\{6\}\)/\1\n/g' filename
考虑一下:
> cat bla
a1|b2|c3|d4|
> sed 's/\(\([^|]\+|\)\{6\}\)/\1\n/g' bla
a1|b2|
c3|d4|
这就是正则表达式的工作原理:
[^|]
是任何非|
字符。[^|]\+
是至少一个非|
字符的序列。[^|]\+|
是至少一个非|
字符后跟|
的序列。\([^|]\+|\)
是至少一个非|
字符后跟|
的序列,组合在一起\([^|]\+|\)\{6\}
是连续6个这样的群体。\(\([^|]\+|\)\{6\}\)
是连续6个这样的群组,组合在一起。替换只需要6个组的序列,并在最后添加换行符。
答案 3 :(得分:2)
以下是我使用awk
awk -v RS="|" '{printf $0 (NR%7?RS:"\n")}' file
field1a|field2a|field3a|field4a|field5a|field6a|[...]
field1d|field2d|field3d|field4d|field5d|field6d|[...]
field1m|field2m|field3m|field4m|field5m|field6m|[...]
field1z|field2z|field3z|field4z|field5z|field6z|
只需将NR%7
字段调整为适合您的字段数。
答案 4 :(得分:1)
如何在六块街区打印线条?
$ awk 'BEGIN{FS=OFS="|"} {for (i=1; i<=NF; i+=6) {print $(i), $(i+1), $(i+2), $(i+3), $(i+4), $(i+5)}}' file
field1a|field2a|field3a|field4a|field5a|field6a
field1d|field2d|field3d|field4d|field5d|field6d
field1m|field2m|field3m|field4m|field5m|field6m
field1z|field2z|field3z|field4z|field5z|field6z
BEGIN{FS=OFS="|"}
将输入和输出字段分隔符设置为|
。{for (i=1; i<=NF; i+=6) {print $(i), $(i+1), $(i+2), $(i+3), $(i+4), $(i+5)}}
循环浏览6个块上的项目。每次打印其中六个。当print
最终写完一个新行时,你就完成了。答案 5 :(得分:1)
如果要将文件视为多行,请将\n
作为字段分隔符。例如,要获取第二列,只需执行:
tr \| \\n < input-file | sed -n 2p
要查看哪些列与正则表达式匹配,请执行:
tr \| \\n < input-file | grep -n regex