Я создаю сценарий, который предлагает пользователю вводить имя файла и искать строки в файле, самую длинную строку и самую короткую строку. Вот то, что я имею.
#!/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.
Извините мое форматирование и или структура. Я на ранних стадиях изучения сценария оболочки и ценю любую справку.
Если Вы готовы использовать немного Python в своем коде, находя, что длина самой короткой строки легка:
python3 -c 'import sys; print(min(map(len, sys.stdin)))' < "$file"
print
и min
должно быть довольно очевидным. map(len, sys.stdin)
применяется len
(длина) функция к каждой записи в 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
печать только первая запись, которая, после сортировки, была бы самая короткая длина строки. Или, полностью в ударе:
{
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
цикл, считанный из него.
В вашем скрипте есть:
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
, длина original_line >), беря только число в начале.
Не используя сценарий, с помощью просто 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.