Мне нужно отсортировать текстовый файл по количеству символов в строке, затем отсортировать его по наименьшему количеству пустых символов, т.е. пробелов, если количество символов в двух строках одинаково. Я понял первую часть, но не могу понять, как сделать вторую. Кто-нибудь может мне помочь?
Я пошел бы с awk
и что-то вроде этого:
awk -F " " '{print length($0), NF-1, $0}' file.txt
Если у Вас есть несколько использования пробелов этот:
awk '{NS=gsub(" "," ",$0); print length($0), NS, $0}' file.txt
gsub
замены каждое пространство с пространством и возвратами количество этого процесса, который является количеством пробелов.Скажем, мы получили файл с этим содержанием:
here is something
here is something el s
here is something else
and agai n
and a a aa
outpout вышеупомянутой команды:
17 2 here is something
22 4 here is something el s
22 3 here is something else
10 2 and agai n
10 3 and a a aa
Первый столбец является количеством символов, вторым является количество пробелов.
Затем мы передаем его по каналу к sort
и sort
сделает задание, и в конце концов я могу использовать сокращение, чтобы только получить исходное содержание файла:
awk -F " " '{print length($0), NF-1, $0}' file.txt | sort -k1n,2 | cut -f3- -d' '
Для второго решения:
awk '{NS=gsub(" "," ",$0); print length($0), NS, $0}' file.txt | \
sort -k1n,2 | cut -f3- -d' '
И окончательный результат:
and agai n
and a a aa
here is something
here is something else
here is something el s
Можно измениться -F " "
с Вашим определенным символом говорят "R":
awk -F "R" ...
или
gsub("R","R",$0)
для второго.
На основе усовершенствованной сортировки от приобретения знаний O'Reilly perl
, Вы могли сделать что-то как
perl -lne '
push @arr, $_ }{
for $x (sort { length($a) <=> length($b) or $a =~ tr/ // <=> $b =~ tr/ // } @arr) {
print $x
}
' file
Заимствование входного образца @ByteCommander,
$ perl -lne '
> push @arr, $_ }{
> for $x (sort { length($a) <=> length($b) or $a =~ tr/ // <=> $b =~ tr/ // } @arr) {
> print $x
> }
> ' loremipsum.txt
Omnis et vitae et blanditiis in et.
Inventore eligendi distinctio perferendis ab.
Nostrum laboriosam et amet illum consectetur.
Molestiae ipsam quis dolores vero a delectus.
Voluptas quos doloribus totam porro inventore.
Aut cupiditate ullam possimus voluptate et delectus tenetur sint.
Если у Вас есть GNU awk 4.0 или позже, можно сделать подобную вещь - хотя пользовательская функция вида берет немного больше работы, например.
$ cat 2sort.awk
#!/usr/bin/gawk -f
function mycmp(ia, a, ib, b) {
n = length(a) - length(b);
return n == 0 ? gsub(/ /,"",a) - gsub(/ /,"",b) : n
}
{arr[NR] = $0}
END {
PROCINFO["sorted_in"] = "mycmp";
for(i in arr) print arr[i];
}
предоставление
$ ./2sort.awk loremipsum.txt
Omnis et vitae et blanditiis in et.
Inventore eligendi distinctio perferendis ab.
Nostrum laboriosam et amet illum consectetur.
Molestiae ipsam quis dolores vero a delectus.
Voluptas quos doloribus totam porro inventore.
Aut cupiditate ullam possimus voluptate et delectus tenetur sint.
Вот немного сценария Python, который делает задание. Обратите внимание, что это удаляет все запаздывающие пробельные символы из каждой строки прежде, чем отсортировать и в выводе.
#!/usr/bin/env python3
import sys
if len(sys.argv) != 2:
print("Error, you must specfy the input file name as only argument!")
exit(1)
lines=[line.rstrip() for line in open(sys.argv[1])]
print(*sorted(sorted(lines, key=lambda b:b.count(" ")), key=lambda a:len(a)),
sep="\n")
Если Вы хотите сократить его, отпуск намечает 3-5, которые только проверяют, что точно один параметр командной строки был дан и печатает сообщение об ошибке если дело обстоит не так.
И вот тестовый прогон:
(со сценарием, сохраненным как sort.py
и сделанное исполняемое использование chmod +x sort.py
)
$ cat loremipsum.txt
Nostrum laboriosam et amet illum consectetur.
Voluptas quos doloribus totam porro inventore.
Molestiae ipsam quis dolores vero a delectus.
Aut cupiditate ullam possimus voluptate et delectus tenetur sint.
Omnis et vitae et blanditiis in et.
Inventore eligendi distinctio perferendis ab.
$ ./sort.py loremipsum.txt
Omnis et vitae et blanditiis in et.
Inventore eligendi distinctio perferendis ab.
Nostrum laboriosam et amet illum consectetur.
Molestiae ipsam quis dolores vero a delectus.
Voluptas quos doloribus totam porro inventore.
Aut cupiditate ullam possimus voluptate et delectus tenetur sint.