向 Grep 添加制表符分隔符
Posted
技术标签:
【中文标题】向 Grep 添加制表符分隔符【英文标题】:Add Tab Separator to Grep 【发布时间】:2011-02-01 00:06:37 【问题描述】:我是 grep 和 awk 的新手,我想在“frequency.txt”文件输出中创建制表符分隔值(此脚本查看一个大型语料库,然后输出每个单词及其使用次数在语料库中-我将其修改为高棉语)。我环顾四周(grep a tab in UNIX),但似乎找不到对我来说对这个 bash 脚本有意义的示例(我太新手了)。
我在 cygwin 中使用这个 bash 脚本:
#!/bin/bash
# Create a tally of all the words in the corpus.
#
echo Creating tally of word frequencies...
#
sed -e 's/[a-zA-Z]//g' -e 's// /g' -e 's/\t/ /g' \
-e 's/[«|»|:|;|.|,|(|)|-|?|។|”|“]//g' -e 's/[0-9]//g' \
-e 's/ /\n/g' -e 's/០//g' -e 's/១//g' -e 's/២//g' \
-e 's/៣//g' -e 's/៤//g' -e 's/៥//g' -e 's/៦//g' \
-e 's/៧//g' -e 's/៨//g' -e 's/៩//g' dictionary.txt | \
tr [:upper:] [:lower:] | \
sort | \
uniq -c | \
sort -rn > frequency.txt
grep -Fwf dictionary.txt frequency.txt | awk 'print $2 "," $1'
Awk 使用逗号打印,但这只是在屏幕上。如何在频率和术语之间放置一个制表符(逗号也可以)?
这是 dictionary.txt 文件的一小部分(高棉语不使用空格,但在这个语料库中,每个单词之间有一个不间断的空格,使用 sed 和正则表达式转换为空格):
ព្រះវិញ្ញាណនឹងប្រពន្ធថ្មោងថ្មីពោលថា អញ្ជើញមក ហើយអ្នកណាដែលឮក៏ថា អញ្ជើញមកដែរ អ្នកណាដែលស្រេក នោះមានតែមក ហើយអ្នកណាដែលចង់បាន មានតែយកទឹកជីវិតនោះចុះ ឥតចេញថ្លៃទេ។
这是频率.txt 现在的示例输出(频率和术语):
25605 នឹង 25043 ជា 22004 បាន 20515 នោះ
我希望输出频率.txt 看起来像这样(其中 TAB 是实际的制表符):
25605TABនឹង 25043TABជា 22004TABបាន 20515TABនោះ
感谢您的帮助!
【问题讨论】:
如果您提供一个样本来说明语料库文件dictionary.txt
的样子会更好,因为我几乎可以肯定您可以通过对awk
的一次调用来替换整个脚本。即不会使用tr, sort, uniq, sed, or grep
我在原始问题中添加了字典文本文件的示例 - 谢谢!
@Nathan 该字典文件使用什么编码?它在我的屏幕上看起来像垃圾:见i.imgur.com/Ao82s.png
@SiegeX 它是 UTF-8 - 大量的东西还不支持高棉 Unicode。
@Nathan 是 dictionary.txt
只是一堆单词,可能不止一个,一行由空格分隔?还是一个单词列表,每行一个单词?
【参考方案1】:
你应该可以用这个替换整个冗长的sed
命令:
tr -d '[a-zA-Z][0-9]«»:;.,()-?។”“|០១២៣៤៥៦៧៨៩'
tr '\t' ' '
评论:
's// /g'
- 前两个斜杠表示重新使用之前的匹配项 [a-z][A-Z]
并用空格替换它们,但它们已被删除,所以这是一个无操作
's/[«|»|:|;|.|,|(|)|-|?|។|”|“]//g'
- 竖线字符不分隔方括号内的替代项,它们是字面意思(不止一个是多余的),等价的将是 's/[«»:;.,()-?។”“|]//g'
(留下一个竖线以防你真的想删除它们)李>
's/ /\n/g'
- 之前,您将制表符替换为空格,现在您将空格替换为换行符
您应该能够通过在uniq
之后将其插入管道中来获得所需的选项卡:
sed 's/^ *\([0-9]\+\) /\1\t/'
如果您希望 AWK 命令输出选项卡:
awk 'BEGINOFS='\t' print $2, $1'
【讨论】:
谢谢丹尼斯。正如你所说,我在添加标签时遇到问题,当我在 uniq 之后添加 sed 's/^ *([0-9]\+) /\1\t/' 脚本在最后停止并且永远不会填充我的频率。文本文件。我是否正确理解您,我只是在 uniq 下方添加 sed 's/^ *([0-9]\+) /\1\t/' 一行? @Nathan:是的,您需要添加必要的管道字符。就像你有uniq -c | \` now, you would need
sed ... | \` (实际上不需要续行反斜杠,因为管道会为您续行)。
谢谢丹尼斯,我从来没有使用过 bash 脚本,所以我不熟悉语法。感谢您花时间帮助我!【参考方案2】:
用“
【讨论】:
是的,这确实有效,但它并不理想,因为现在屏幕上没有任何正在发生的状态(除了我的 cpu 显示器,我不知道它正在工作)。还有其他方法吗?谢谢你 - 至少这是可能的。【参考方案3】:下面的脚本应该可以带你去你需要去的地方。到tee
的管道将让您在屏幕上看到输出,同时将输出写入./outfile
#!/bin/sh
sed ':a;N;s/[a-zA-Z0-9។០១២៣៤៥៦៧៨៩\n«»:;.,()?”“-]//g;ta' < dictionary.txt | \
gawk '$0=toupper($0);for(i=1;i<=NF;i++)a[$i]++
ENDfor(item in a)printf "%s\t%d ", item, a[item]' | \
tee ./outfile
【讨论】:
以上是关于向 Grep 添加制表符分隔符的主要内容,如果未能解决你的问题,请参考以下文章