[英]Split a big txt file to do grep - unix
我使用txt文件(unix,shell腳本),這些txt文件通過管道用數百萬個字段分隔,而不用\\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
)
當我需要查找一個字段(例如field2
)時,像grep這樣的命令不起作用(在同一行中)。
我認為一個好的解決方案可以是使用“ \\ n”分割每6個字段的腳本,然后再執行grep。 我是正確的? 非常感謝你!
用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|
在這里,您可以輕松設置行的長度。
希望這可以幫助 !
您可以使用sed
將行拆分為多行:
sed 's/\(\([^|]*|\)\{6\}\)/\1\n/g' input.txt > output.txt
說明:
我們必須對(){}
使用大量的反斜杠轉義,這會使代碼有些難以理解。
簡而言之:
s/
和/\\1
之間s/
(([^|]*|){6})
術語(([^|]*|){6})
為了可讀性刪除了反斜杠)將匹配:
[^|]*
除'|'以外的任何字符,重復多次
|
后跟一個“ |”
上面的內容顯然是一欄,並與括起來的括號(
和)
組合在一起
整個組重復6次{6}
然后再將其與括起來的括號(
和)
組合在一起,形成一個完整的集合
該術語的其余部分很容易理解:
將上述(6個字段的整個數據集)替換為\\1\\n
( /
和/g
之間的部分)
\\1
表示sed-expression中的“第一個”組(已啟動的“第一個”組,因此是6個字段的整個數據集)
\\n
是換行符
因此,請自行替換6個字段的整個數據集,然后再換行
並重復這樣做(結尾的g
)
您可以使用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個組的順序進行,並在末尾添加換行符。
這是我將如何使用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
調整為適合您的字段數即可。
怎樣將行打印在六個塊上?
$ 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
最終寫出新行時,就完成了。 如果要將文件視為多行,請使用\\n
字段分隔符。 例如,要獲取第二列,只需執行以下操作:
tr \| \\n < input-file | sed -n 2p
要查看哪些列與正則表達式匹配,請執行以下操作:
tr \| \\n < input-file | grep -n regex
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.