簡體   English   中英

拆分一個大的txt文件以執行grep-UNIX

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM