如何找到剧本中最短的一行

如何找到剧本中最短的一行

我正在创建一个脚本,提示用户输入文件名并搜索文件中的行、最长的行和最短的行。这是我所拥有的。

#!/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的组合:sorthead

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"它适用于该部分的全部内容,以便第一个readwhile循环都可以从中读取。

答案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, <原始行的长度>) 仅取开头的数字。

相关内容