LINUX.ORG.RU

perl Обработка массива

 


1

2

Как на perl написать такое, что делает этот однострочник.

ls -l | perl -lane 'print "$F[8]"'
Не могу сообразить как написать внутри скрипта. ls - взят в качестве примера.


Ответ на: комментарий от Deleted

Для не понятливых:

#!/usr/bin/perl
use warnings;
use strict;

my @arr= `ls -l`;

Как дальше получить, то что делает однострочник в стартовом посте.

joo
() автор топика
$F[8]

Что-то я не могу найти $F в perlvar. Я так понимаю однострочник печатает колонку с индексом 8?

UPD Нашел:

-a                autosplit mode with -n or -p (splits $_ into @F)

Если правильно все понимаю, то:

for my $line (@arr) {
  print((split /\s+/, $line)[8], "\n");
}

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 4)
Ответ на: комментарий от Anoxemian

Так лучше, да. У KennyMinigun тоже лучше.

Но если ОП не понимает самых базовых вещей - то мой пример чуть наглядней и в нем легко понять что происходит. А так да, производительность в моем случае будет хуже некуда.

Kronick
()
Ответ на: комментарий от Kronick

в твоем примере хуже потому, что внутри цикла массив собирается? Это сильно скажется на производительности?

joo
() автор топика
Ответ на: комментарий от joo

Ну лишние инициализации, лишние ресурсы. Если по всему проекту такое будет - то нормально скажется.

Хотя по моему опыту, там где нужна скорость - там перл не используют. И если уж на нем писать - то лучше бы писать читабельно и подробно, иначе вот к примеру лично ты вольешься в проект, в котором будет понапичкано:

"print (map {split /\s+/} `ls -l`)[8];"

Не разберешься и начнешь втыкать костыли, будет очень много разнородного кода. Ну и через какое-то количество лет проект может превратиться в кучу нечитабельной лапши, в которой вообще никто не разберется. Я лично видел как оно бывает.

Ну а если нужна скорость и работают опытные люди, которые понимают что они делают, вот тогда лучше писать хороший, оптимизированный код.

Kronick
()
#!/usr/bin/env perl

use strict;
use warnings;

opendir( my $dh, '.');

for ( grep !/^\./, sort readdir($dh) ) {
  print "$_\n";
}
anonymous
()
Ответ на: комментарий от anonymous

Можно короче:

#!/usr/bin/env perl

use v5.20;

opendir( my $dh, '.' );

say foreach grep !/^\./, sort readdir($dh);
Одним махом подключаем strict, warings и say:
use v5.20;
Вместо for использую foreach. Данные ключевые слова полные синонимы, но принято с помощью for обрабатывать счётчики, а foreach молотит списки.

Краткая (aka постфиксная) запись цикла помещает текущий элемент в переменную по умолчанию ($_).

Если print или say вызываются без аргументов, то в качестве аргумента передаётся значение $_

Следующие три строки аналогичны:

say;
say $_;
print "$_\n";
Выше несколько примеров вроде:
print $ta[8] . "\n";
Не делай так. Используй интерполяцию.

perl5_guy ★★★★★
()
Ответ на: комментарий от perl5_guy

Данные ключевые слова полные синонимы, но принято с помощью for обрабатывать счётчики, а foreach молотит списки.

Где принято? Книга с верблюдом рекомендует for

annulen ★★★★★
()
Ответ на: комментарий от annulen

Не вспомню. Тоже в какой-то книге прочитал. Использовать for для циклов в C-style или

for (0..42) {
...
}
Если интересуют элементы списка непосредственно — используем foreach:
foreach my $camel (@camels) {
...
}

perl5_guy ★★★★★
()
Ответ на: комментарий от perl5_guy

Самое во всём этом занятное - это то, что у ТС ввод читается с STDIN, про который здесь никто ничего так и не написал.

DRVTiny ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.