我正在创建一个脚本,提示用户输入文件名并搜索文件中的行、最长的行和最短的行。这是我所拥有的。
#!/bin/bash
echo -n "Enter a filename:"
read file
if [ -e "$file" ]
then
wc -l $file; echo "lines" && wc -L $file; echo "longest"
echo "$file exists"
else
echo "$file does not exist"
fi
这是我用于测试的文本文件的内容。希望这会有所帮助。
~$ cat simple.txt
I have too many things to do today.
It's going to take to long to get everything done.
My day is very busy.
Why such a long face.
请原谅我的格式和结构。我正处于学习 shell 脚本的早期阶段,非常感谢您的帮助。
答案1
如果您愿意在代码中使用一些 Python,那么找到最短线的长度很容易:
python3 -c 'import sys; print(min(map(len, sys.stdin)))' < "$file"
print
并且min
应该相当明显。map(len, sys.stdin)
将len
(length) 函数应用于 中的每个条目sys.stdin
,即标准输入中的每一行。由于这会将换行符计入行的长度,因此最小长度将比您预期的长 1。要解决此问题:
python3 -c 'import sys; print(min(map(len, sys.stdin.read().splitlines())))' < "$file"
否则,和awk
的组合:sort
head
awk '{print length}' "$file" | sort | head -1
head -1
只打印第一个条目,排序后,该条目的行长最短。或者,完全在 bash 中:
{
IFS= read -r line
min=${#line}
while IFS= read -r line
do
length=${#line}
((min > length)) && min=$length
done
} < "$file"
echo "shortest line's length is $min"
这里,我习惯{ }
将代码部分括起来。这样,< "$file"
它适用于该部分的全部内容,以便第一个read
和while
循环都可以从中读取。
答案2
不使用脚本,仅使用 AWK:
awk 'NR==1{x=$0}{length($0)<length(x)&&x=$0;length($0)>length(y)&&y=$0}END{print "Shortest: "x"\nLongest: "y}' in
如果您希望它提示输入文件名:
awk 'NR==1{x=$0}{length($0)<length(x)&&x=$0;length($0)>length(y)&&y=$0}END{print "Shortest: "x"\nLongest: "y}' "$(read -p "Enter a filename:" x; printf "$x\n")"
将其拆分为两个不同的命令:
awk 'NR==1{x=$0}length($0)<length(x){x=$0}END{print x}' in # shortest line
awk 'length($0)>length(x){x=$0}END{print x}' in # longest line
如果您希望他们提示输入文件名:
awk 'NR==1{x=$0}length($0)<length(x){x=$0}END{print x}' "$(read -p "Enter a filename:" x; printf "$x\n")" # shortest line
awk 'length($0)>length(x){x=$0}END{print x}' "$(read -p "Enter a filename:" x; printf "$x\n")" # longest line
$ cat in
I have too many things to do today.
It's going to take to long to get everything done.
My day is very busy.
Why such a long face.
$ awk 'NR==1{x=$0}{length($0)<length(x)&&x=$0;length($0)>length(y)&&y=$0}END{print "Shortest: "x"\nLongest: "y}' in
Shortest: My day is very busy.
Longest: It's going to take to long to get everything done.
$ awk 'NR==1{x=$0}{length($0)<length(x)&&x=$0;length($0)>length(y)&&y=$0}END{print "Shortest: "x"\nLongest: "y}' "$(read -p "Enter a filename:" x; printf "$x\n")"
Enter a filename:in
Shortest: My day is very busy.
Longest: It's going to take to long to get everything done.
答案3
您的脚本中有:
wc -l $file; echo "lines" && wc -L $file; echo "longest"
你可以用以下方法改变它:
LENGTH=$(<"$file" wc -l)
LONGEST=$(while read thisline; do echo "$(<<<"$thisline" wc -L) $thisline";done <"$file"|grep -v '^0 '|sort -t" "|tail -1|awk '{print $1}')
echo "$LENGTH lines, $LONGEST longest"
就是这样,对脚本输出进行一些修复。
创建while
一个新的数据流,包含文件中每行的长度。grep
排除空行(长度为 0 个字符);您的情况中没有空行,但预防胜于治疗。然后sort
按升序排列行长,并tail
获取最后一行,即数字最高(最长的行长)。awk
是否有清理输出(来自wc
, <原始行的长度>) 仅取开头的数字。