在 bash 中将一个文件的行数除以另一个文件的行数的最短行数是多少?
What is the shortest one-liner to divide the line count of one file by another in bash?
在 bash shell 中,我试图编写一个简短的单行代码,将一个文件的行数除以另一个文件的行数。我想显示浮点除法的至少两位小数。
换句话说,我想要一个单行打印一个文件的行数占另一个文件行数的百分比。
例如,如果我有一个 25 行的第一个文件 (first.txt) 和一个 100 行的第二个文件 (second.txt),单行代码将输出 .25
.
下面将两个文件的行数存储在两个变量中。使用 sed
和 cut
从 wc
的输出中删除文件名和前导空格。然后使用 bc
.
对两个变量执行除法
count1=$(wc -l first.txt | sed -e 's/^[[:space:]]*//' | cut -f 1 -d ' ') && count2=$(wc -l second.txt | sed -e 's/^[[:space:]]*//' | cut -f 1 -d ' ') && echo "scale=2; $count1/$count2" | bc
或者,您可以将 gawk
用作:
gawk 'NR==FNR{a+=1;next} {b+=1} END{printf "%.2f\n", a/b}' first.txt second.txt
我能想出的最短的使用命令替换和重定向
$ echo "scale=2; $(wc -l <first.txt) / $(wc -l <second.txt)" | bc
.25
如果您有任何问题,请告诉我。
使用 bc
和 grep
的最短版本
echo "$(grep -c '$' file1) / $(grep -c '$' file2)" | bc -l
另一个 GNU awk 答案,使用了一堆内置变量
:
gawk '
ENDFILE {nr[FILENAME] = FNR}
END {printf "%.2f\n", nr[ARGV[1]] / nr[ARGV[2]]}
' first.txt second.txt
首先进行一些测试material:
$ for i in {1..25} ; do echo $i >> first ; done
$ for i in {1..100} ; do echo $i >> second ; done
然后一些 awk:
$ awk 'END{print(NR-FNR)/FNR}' first second
0.25
NR
是两个文件中的记录总数。 END
处FNR
是后一个文件的记录数,所以(NR-FNR)/FNR
是第一个文件的记录数除以第二个文件的记录数。
除了此处提供的解决方案,您还需要将问题提交给 the code golf course。
一次性使用
echo `wc -l <first.txt`/`wc -l <second.txt`|bc -l
一个脚本使用
e(){ echo `wc -l <`/`wc -l <` | bc -l;}
e first.txt second.txt
一个用户使用:添加函数到.bashrc
大家使用:添加函数到/etc/bash.bashrc
bash-4.4$ a=$(perl -e "print $(cat file1|wc -l) /$(cat file2|wc -l)")
bash-4.4$ echo $a
0.333333333333333
编辑答案以支持小数值
所有 bc
答案的替代方法:
dc <<< "2k $(wc -l < file1) $(wc -l < file2) /p"
2k
设置精度,这里输出总是有两位小数。
在 bash shell 中,我试图编写一个简短的单行代码,将一个文件的行数除以另一个文件的行数。我想显示浮点除法的至少两位小数。
换句话说,我想要一个单行打印一个文件的行数占另一个文件行数的百分比。
例如,如果我有一个 25 行的第一个文件 (first.txt) 和一个 100 行的第二个文件 (second.txt),单行代码将输出 .25
.
下面将两个文件的行数存储在两个变量中。使用 sed
和 cut
从 wc
的输出中删除文件名和前导空格。然后使用 bc
.
count1=$(wc -l first.txt | sed -e 's/^[[:space:]]*//' | cut -f 1 -d ' ') && count2=$(wc -l second.txt | sed -e 's/^[[:space:]]*//' | cut -f 1 -d ' ') && echo "scale=2; $count1/$count2" | bc
或者,您可以将 gawk
用作:
gawk 'NR==FNR{a+=1;next} {b+=1} END{printf "%.2f\n", a/b}' first.txt second.txt
我能想出的最短的使用命令替换和重定向
$ echo "scale=2; $(wc -l <first.txt) / $(wc -l <second.txt)" | bc
.25
如果您有任何问题,请告诉我。
使用 bc
和 grep
echo "$(grep -c '$' file1) / $(grep -c '$' file2)" | bc -l
另一个 GNU awk 答案,使用了一堆内置变量 :
gawk '
ENDFILE {nr[FILENAME] = FNR}
END {printf "%.2f\n", nr[ARGV[1]] / nr[ARGV[2]]}
' first.txt second.txt
首先进行一些测试material:
$ for i in {1..25} ; do echo $i >> first ; done
$ for i in {1..100} ; do echo $i >> second ; done
然后一些 awk:
$ awk 'END{print(NR-FNR)/FNR}' first second
0.25
NR
是两个文件中的记录总数。 END
处FNR
是后一个文件的记录数,所以(NR-FNR)/FNR
是第一个文件的记录数除以第二个文件的记录数。
除了此处提供的解决方案,您还需要将问题提交给 the code golf course。
一次性使用
echo `wc -l <first.txt`/`wc -l <second.txt`|bc -l
一个脚本使用
e(){ echo `wc -l <`/`wc -l <` | bc -l;}
e first.txt second.txt
一个用户使用:添加函数到.bashrc
大家使用:添加函数到/etc/bash.bashrc
bash-4.4$ a=$(perl -e "print $(cat file1|wc -l) /$(cat file2|wc -l)")
bash-4.4$ echo $a
0.333333333333333
编辑答案以支持小数值
所有 bc
答案的替代方法:
dc <<< "2k $(wc -l < file1) $(wc -l < file2) /p"
2k
设置精度,这里输出总是有两位小数。