Linux 计算Unix上每行/每字段出现的字符数
给定一个包含如下数据的文件(即stores.dat文件) 返回每行“t”字符出现次数的命令是什么 他将返回:Linux 计算Unix上每行/每字段出现的字符数,linux,bash,shell,unix,scripting,Linux,Bash,Shell,Unix,Scripting,给定一个包含如下数据的文件(即stores.dat文件) 返回每行“t”字符出现次数的命令是什么 他将返回: count lineNum 4 1 3 2 6 3 另外,要按字段计数,返回以下结果的命令是什么 例如,输入第2列和字符“t” count lineNum 1 1 0 2 1 3 count lineNum 2 1 1 2
count lineNum
4 1
3 2
6 3
另外,要按字段计数,返回以下结果的命令是什么 例如,输入第2列和字符“t”
count lineNum
1 1
0 2
1 3
count lineNum
2 1
1 2
4 3
例如,输入第3列和字符“t”
count lineNum
1 1
0 2
1 3
count lineNum
2 1
1 2
4 3
要计算每行字符的出现次数,可以执行以下操作:
awk -F'|' 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"") "\t" NR}' file
count lineNum
4 1
3 2
6 3
要计算每个字段/列中字符的出现次数,可以执行以下操作:
awk -F'|' 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"") "\t" NR}' file
count lineNum
4 1
3 2
6 3
第2列:
awk -F'|' -v fld=2 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"",$fld) "\t" NR}' file
count lineNum
1 1
0 2
1 3
awk -F'|' -v fld=3 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"",$fld) "\t" NR}' file
count lineNum
2 1
1 2
4 3
第3列:
awk -F'|' -v fld=2 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"",$fld) "\t" NR}' file
count lineNum
1 1
0 2
1 3
awk -F'|' -v fld=3 'BEGIN{print "count", "lineNum"}{print gsub(/t/,"",$fld) "\t" NR}' file
count lineNum
2 1
1 2
4 3
函数的返回值是替换的次数。所以我们用它来打印数字李>gsub()
保存行号,因此我们使用它来打印行号李>NR
- 为了打印特定字段的出现情况,我们创建了一个变量
,并放置我们希望从中提取计数的字段编号李>fld
- 使用
的一种可能的解决方案: script.pl的内容:perl
使用参数及其输出: 这里0是一个坏列,它搜索所有行use warnings; use strict; ## Check arguments: ## 1.- Input file ## 2.- Char to search. ## 3.- (Optional) field to search. If blank, zero or bigger than number ## of columns, default to search char in all the line. (@ARGV == 2 || @ARGV == 3) or die qq(Usage: perl $0 input-file char [column]\n); my ($char,$column); ## Get values or arguments. if ( @ARGV == 3 ) { ($char, $column) = splice @ARGV, -2; } else { $char = pop @ARGV; $column = 0; } ## Check that $char must be a non-white space character and $column ## only accept numbers. die qq[Bad input\n] if $char !~ m/^\S$/ or $column !~ m/^\d+$/; print qq[count\tlineNum\n]; while ( <> ) { ## Remove last '\n' chomp; ## Get fields. my @f = split /\|/; ## If column is a valid one, select it to the search. if ( $column > 0 and $column <= scalar @f ) { $_ = $f[ $column - 1]; } ## Count. my $count = eval qq[tr/$char/$char/]; ## Print result. printf qq[%d\t%d\n], $count, $.; }
在这里,它在第1列中搜索perl script.pl stores.dat 't' 0 count lineNum 4 1 3 2 6 3
在这里,它在第3列中搜索perl script.pl stores.dat 't' 1 count lineNum 0 1 2 2 0 3
perl script.pl stores.dat 't' 3 count lineNum 2 1 1 2 4 3
不是字符th
perl script.pl stores.dat 'th' 3 Bad input
其中,
将是您要计算的列号。不需要awk或perl,只需要使用bash和标准Unix实用程序:$1
对于特定列:cat file | tr -c -d "t\n" | cat -n | { echo "count lineNum" while read num data; do test ${#data} -gt 0 && printf "%4d %5d\n" ${#data} $num done; }
我们甚至可以避免cut -d "|" -f 2 file | tr -c -d "t\n" | cat -n | { echo -e "count lineNum" while read num data; do test ${#data} -gt 0 && printf "%4d %5d\n" ${#data} $num done; }
和tr
s:cat
echo "count lineNum" num=1 while read data; do new_data=${data//t/} count=$((${#data}-${#new_data})) test $count -gt 0 && printf "%4d %5d\n" $count $num num=$(($num+1)) done < file
和事件切割:echo“count lineNum” num=1 读取数据时;做 new_data=${data//t/} 计数=$(${数据}-${新数据})) 测试$count-gt 0&&printf“%4d%5d\n”$count$num num=$($num+1)) 完成<文件
echo "count lineNum" num=1; OLF_IFS=$IFS; IFS="|" while read -a array_data; do data=${array_data[1]} new_data=${data//t/} count=$((${#data}-${#new_data})) test $count -gt 0 && printf "%4d %5d\n" $count $num num=$(($num+1)) done < file IFS=$OLF_IFS
提供几乎完全符合您需要的输出:echo“count lineNum” num=1;OLF_IFS=$IFS;IFS=“|” 读取时-数组_数据;做 data=${array_data[1]} new_data=${data//t/} 计数=$(${数据}-${新数据})) 测试$count-gt 0&&printf“%4d%5d\n”$count$num num=$($num+1)) 完成<文件 IFS=$OLF_IFS
4 1 3 2 6 3
感谢@raghav bhushan提供的
提示,这是一个多么有用的标志。-n标志也包括行号。您还可以使用“t”拆分行或字段,并检查结果数组-1的长度。将行的grep-o
变量设置为0,或将列的col
变量设置为1到3:
$ cat -n test.txt 1 test 1 2 you want 3 void 4 you don't want 5 ttttttttttt 6 t t t t t t $ awk '{n=split($0,c,"t")-1;if (n!=0) print n,NR}' test.txt 2 1 1 2 2 4 11 5 6 6
对gsub()的调用删除行中所有不是t的内容,然后只打印剩余内容的长度和当前行号 想只为第二栏做吗awk -F'|' -v col=0 -v OFS=$'\t' 'BEGIN { print "count", "lineNum" }{ split($col, a, "t"); print length(a) - 1, NR } ' stores.dat
awk 'BEGIN{FS="|"} {gsub("[^t]","",$2); print NR,length($2);}' stores.dat
要计算每行出现的字符数,请执行以下操作:
这将字段分隔符设置为需要计数的字符,然后使用字段数比分隔符数大一的事实 要计算特定列中的发生次数,请首先剪切该列:$ awk -F 't' '{print NF-1, NR}' input.txt 4 1 3 2 6 3
$ cut -d '|' -f 2 input.txt | awk -F 't' '{print NF-1, NR}' 1 1 0 2 1 3 $ cut -d '|' -f 3 input.txt | awk -F 't' '{print NF-1, NR}' 2 1 1 2 4 3
perl-e'while(){$count=tr/t/;打印“$count”。++$x.“\n”}”stores.dat
又是一个perl答案耶!tr/t//函数返回该行上发生翻译的次数,换句话说,tr找到字符“t”的次数+$x维护行号计数 看一看,它是一个非常强大的unix工具,很多时候都是这样,但是接受另一个答案,更容易与Bash集成这是一个更加优雅和通用的解决方案。我认为可以省去
,输出不是按行号顺序吗?这很奇怪,确切的命令返回“10t”、“11”、“12”、“13”在我的Mac电脑上。@Gabrial Burt,你能在回答中解释一下每一步吗。。你的命令是什么,它们的修饰词如何影响正在发生的事情?如果你的Mac代码> GRP是奇怪的,考虑<代码> BREW安装< /代码>来获取和使用<代码> pCREGRIP。它打印“0”(发生)同样,这在未来可能并不理想output@TarunSapra它实际上显示为问题中的预期结果。请注意,sort-n
将更改记录的内容。如果需要原始值,应在其他操作块之后调用gsub()
(或将原始内容保存在变量中)。gsub()
perl -e 'while(<>) { $count = tr/t//; print "$count ".++$x."\n"; }' stores.dat