我有一个问题听起来像这样:编写一个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
答案 0 :(得分:2)
挑战是:
k
长的单词数。输出必须按字数排序。我拒绝回答提示 - 命令接受参数。我和William 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
内置的结果进行排序。
答案 1 :(得分:1)
您可以稍微简化脚本:
#!/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
会跳过count小于$k
sort
- 用于排序输出在@Tom Fench here的帮助下,它可以简化为:
wc -w "$@" | awk -v k="$k" 'NR>1&&p>k{print p}{p=$1}' | sort -nr
或使用文件名(基于@ Wintermute的评论here)
wc -w "$@" | awk -v k="$k" 'p { print p; p="" } $1 > k { p = $0 }' | sort -nr
根据@Jonathan Leffler的评论添加一个变体,用于计算每个文件中数字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