Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Сортировка строк по длине (Shell) / 10 сообщений из 10, страница 1 из 1
30.05.2006, 09:14
    #33759592
Davido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Не подскажите как лучше написать сортировку строк файла по длине (shell процедурой). У меня была идея в начало каждой строки вставлять длину строки, потом сортировать файл по первому полю, а потом в отстортированном файле удалять это первое поле. Но выражение
"`expr $val : '.*'` - $val"
даже не хочет выполнятся (или оно считает количество символов только в строке без разделителей!?

Так же ввело меня в ступор попытка удалить первую колонку в каждой строке.
Помогите, пожалуйста - мне это надо для зачетной лабороторной, которую почти всю я уже написала, осталось только это :(
...
Рейтинг: 0 / 0
30.05.2006, 09:40
    #33759644
--null--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Насчет разделителей - в кавычки надо брать строку.

если делать как Вы хотите - должно быть что-то типа того

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#!/bin/sh
{
while read a
do
echo `expr length "$a"`:$a
done <test.txt
} | sort -t: -n | cut -d: -f2

но это упрощенный вариант: разделитель ( в данном случае ::" может встречаться еще в строке - и тогда все поедет поэтому
или надо придумывать уникальный разделитель или что правильнее - на время обработки
заменять разделитель некоей своей escape-последовательностью
а потом вертать назад.
...
Рейтинг: 0 / 0
30.05.2006, 10:55
    #33759835
Davido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Спасибо Вам за помощь, к сожалению у меня не работает предложенный вами код в моей процедуре, я делаю так

echo "Vvedite imya novogo faila"
read f2
f1=$1
cnt=`wc -l < $f1`
i=0
r=0
{
while [ $i -le $cnt ]
do
r=`expr $cnt - $i`
val=`tail -$r $f1 | head -1`
i=`expr $i + 1`
echo `expr length "$val"`:$val
shift
done < $f2
} | sort -t: n | cut -d: -f2
cnt2=`expr $cnt / 2`
i=0
b=0
e="_"
while [ $i -le $cnt2 ]
do
head -$cnt $f1 | tail -2
cnt=`expr $cnt - 2`
i=`expr $i + 1`
read -t 6 e
if test $e = "end"
then
b=`expr $b + 1`
fi
if [ $b -eq 3 ]
then
rm $f2
exit
fi
e="_"
done


в файл $f2 у меня ничего не записывается, и соответсвенно команда sort выдает ошибку.
...
Рейтинг: 0 / 0
30.05.2006, 11:17
    #33759930
--null--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
интересно, что не работает? В какой строке пишет ошибку?

А по Вашему коду ничего и не будет записываться.
Вы вводите "имя нового файла"

echo "Vvedite imya novogo faila"
read f2


а потом зачем-то из него что-то пытаетесь перенаправить,

....
done < $f2

хотя я не виду попытки прочитать данные.
В любом случае как после этого файл $f2 будет что-то содержать?

и вообще как-то всего неоправданно много действий (imho).
...
Рейтинг: 0 / 0
30.05.2006, 11:31
    #33759992
--null--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Опции expr для обработки строк, к сожалению, плохо стандартизированы, поэтому для получения длины строки можно применить awk, что портабельнее

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#!/bin/sh
{
while read a
do
  echo $a | awk '{print length($0) ":" $0}'
done <test.txt
} | sort -t: -n | cut -d: -f2
...
Рейтинг: 0 / 0
30.05.2006, 11:39
    #33760034
Davido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
на счет того что много лишнего согласна с Вами (к сожалению плохо знаю shell программирование)
переписала вот так (мне нужно сохранять первый файл, а результат перенаправлять в новый)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
echo "Vvedite imya novogo faila"
read f2
f1=$1
cnt=`wc -l $f1`
cp $f1 $f2
{
while read a
do
 echo `expr length "$a"`:$a
done < $f2
} | sort -t: n | cut -d: -f2

на сколько я понимаю, результат работы выводится на экран, а что бы его записать в тот же файл, нужно перенаправить вывод, да?
...
Рейтинг: 0 / 0
30.05.2006, 11:53
    #33760111
--null--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
у sort дефисы не забываем :-)
и не надо ничего копировать - читайте из оригинального и перенаправьте в другой файл

sort -t: n | cut -d: -f2 > newfile.txt


cnt этот выбросить, он не нужен никому

вообще перечитайте материал, очень несистематизировано усвоили поэтому много лишних и бессмысленных действий.
...
Рейтинг: 0 / 0
30.05.2006, 14:26
    #33760788
Davido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Спасибо за помощь. В итоге по заданию:
Написать shell-процедуру, которая выполняет действия:
- читает содержимое файла, имя которого передается в качестве параметра;
- создает новый файл, имя которого передается в качестве параметра;
- выводит на экран каждые 6 секунд очередные 2 строки файла в обратном порядке;
- сортирует выведенные на экран строки по длине и записывает их в новый файл;
- при вводе с клавиатуры трижды слова end удаляет второй файл и завершает работу.

Получилась вот такая процедура (правда без проверки на существование файла входного файла). Может быть какому-нибудь неродивому студенту как мне пригодится :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
echo "Vvedite imya novogo faila"
read f2
f1=$ 1 
{
while read a
do
echo `expr length "$a"`:$a
done < $f1
} | sort -t: -n | cut -d: -f2 > $f2
echo "fail make..."
cnt=`wc -l < $f1`
i= 0 
b= 0 
e="_"
while [ $i -le $cnt ]
do
 head -`expr $cnt - $i` $f1 | tail - 2 
 i=`expr $i +  2 `
 read -t  6  e
 if test $e = "end"
 then
  b=`expr $b +  1 `
 fi
 if [ $b -eq  3  ]
 then
  rm $f2
  exit
 fi
 e="_"
done
...
Рейтинг: 0 / 0
31.05.2006, 09:31
    #33762295
Davido
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
было время дописала проверки, хм - начинаю даже понимать как все это писать :-)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
if [ "$#" -lt  1  ]
then
 echo "Ne ukazan vhodnoi parametr (fail)"
 exit
else
 if test -f $ 1 
 then
  echo "Vvedite imya novogo faila" 
  read f2
  if test -z "$f2"
  then
   echo "Imya faila ne mojet byt' pustym"
   exit
  else
   f1=$ 1 
   {
   while read a
   do
    echo `expr length "$a"`:$a
   done < $f1
   } | sort -t: -n | cut -d: -f2 > $f2
   echo "fail make..."
   cnt=`wc -l < $f1`
   i= 0 
   b= 0 
   e="_"
   while [ $i -le $cnt ]
   do
    head -`expr $cnt - $i` $f1 | tail - 2 
    i=`expr $i +  2 `
    read -t  6  e
    if test -z "$e"
    then
     e=""
    else
     if test $e = "end"
     then
      b=`expr $b +  1 `
     fi
     if [ $b -eq  3  ]
     then
      rm $f2
      exit
     fi
     e=""
    fi
   done
  fi
 else
  echo "Vhodnoi parametr ne fail"
 fi
fi
...
Рейтинг: 0 / 0
31.05.2006, 09:42
    #33762308
--null--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка строк по длине (Shell)
Davido, не очень хороший стиль так писать - сочетание проверок и длинных блоки.

Гораздо лучше - проверить и если не файл - сразу выход


Код: plaintext
1.
2.
3.
4.
[ ! -f "$1" ] && {
echo "Vhodnoi parametr ne fail"
exit  1 
}

и дальше по умолчанию - продолжение банкета


тогда получается впереди короткая проверка и дальше основное действие,
без таких длинных блоков условий, как сейчас.
Скрипт станет легче читать.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Сортировка строк по длине (Shell) / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]