我有一个听起来像这样的问题:写一个shell脚本,用于在命令行中的每个文件将输出比从键盘读取数k较长的单词的数量。 输出必须通过单词的数量进行排序。
我怎样才能留住每一个文件的字符数,对它们进行排序?
我想类似的东西:
#!/bin/bash
if [ #@ -ne 1 ]
then exit 1
fi
array[$@]=''
echo -n "Give the number>"
read k
for f in $@;
do
n=`$f | wc -c`
if [ $n -gt $k ];
then
i++
array[i]=$n
fi
done
echo {array[@]} | sort -n
面临的挑战是:
- 写一个shell脚本,从命令行将输出的每个文件比数较长的单词数量
k
从键盘读取。 输出必须通过单词的数量进行排序。
我拒绝回答提示 - 命令带有参数。 我会与威廉Pursell的建议,即数是第一个参数去 - 这是一个合理的解决方案。 一种替代使用像一个选项-l 23
的长度(和其他选项来调整其它操作)。
我看到到目前为止,解决方案计数的单词数,但不言大于给定长度更长的数量。 这是个问题。 对于这一点,我认为awk
是合适的:
awk -v min=$k '{ for (i = 1; i <= NF; i++) if (length($i) >= min) print $i; }'
这至少产生词语min
字符在标准输出每行一个。 我们会做一次这样一个文件,至少在第一关。
然后,我们可以算这样的词的数量wc -l
。 最后,我们可以将数据排序数字。
综合起来,得出:
#!/bin/bash
case "$#" in
0|1) echo "Usage: $0 length file ..." >&2; exit 1;;
esac
k=${1:?"Cannot provide an empty length"}
shift
for file in "$@"
do
echo "$(awk -v min=$k '{ for (i = 1; i <= NF; i++)
if (length($i) >= min) print $i
}' "$file" |
wc -l) $file"
done | sort -n
这将列出与去年最长的单词的文件; 因为最有趣的文件在列表的末尾这是方便。 如果你首先要高的数字,加上-r
的sort
。
当然,如果我们使用awk
,我们可以改善的事情。 它可以指望的长单词的数量在每个文件和打印文件的名称和数量,所以会是仅仅的一次调用awk
所有文件。 这需要多一点点编程,但:
#!/bin/sh
case "$#" in
0|1) echo "Usage: $0 length file ..." >&2; exit 1;;
esac
k=${1:?"Cannot provide an empty length"}
shift
awk -v min=$k '
FILENAME != oldfile { if (oldfile != "") { print longwords, oldfile }
oldfile = FILENAME; longwords = 0
}
{ for (i = 1; i <= NF; i++) if (length($i) >= min) longwords++ }
END { if (oldfile != "") { print longwords, oldfile } }
' "$@" |
sort -n
如果你有GNU awk
,甚至有办法建成对结果进行排序awk
。
您可以简化脚本了一下:
#!/bin/bash
(( $# > 0 )) || exit
read -r -p 'Enter number > ' k
wc -w "$@" | sed '$d' | gawk -v k="$k" '$1>k{print $0}' | sort -nr
哪里
-
read -r -p ...
提示和读取输入 -
wc -w
-重要的东西,你作为参数输入的所有文件的话 -
sed ...
-跳过最后一行(total...)
-
awk
跳过线,其中计数小于$k
-
sort
-排序的输出
随着@汤姆Fench的很大的帮助在这里它可以简化为:
wc -w "$@" | awk -v k="$k" 'NR>1&&p>k{print p}{p=$1}' | sort -nr
或文件名(@ Wintermute的评论基于这里 )
wc -w "$@" | awk -v k="$k" 'p { print p; p="" } $1 > k { p = $0 }' | sort -nr
编辑
基于@Jonathan莱弗勒的评论增加了用于计算的话什么都不再像数的变异k
在每个文件。
#!/bin/bash
(( $# > 0 )) || exit
read -r -p 'Enter number > ' k
let k++
grep -HoP "\b\w{${k:-3},}\b" "$@" |\
awk -F: '{f[$1]++}END{for(n in f)print f[n],n}' |\
sort -nr
哪里:
- 在
grep...
搜索什么是不再作为输入的数字的话(省略let
如果想要平等和更长的线)。 打印出线条状:
file1:word1
file1:word2
...
file2:wordx
file2:wordy
- 和AWK计数基于所述第一字段,例如,频率由filename计数。