Как добавить столбец в начало файла с помощью Perl?

Создание учетной записи

При предоставлении кому-то доступа к системе Linux Вы обычно используете команду useradd.

$ useradd someuser

Предоставление разрешения файловой системы

Если пользователь будет работать с какими-либо файлами в системе, то добавьте их к соответствующим группам, на основе которых файлов они будут работать с. Можно использовать usermod команда для этого.

$ usermod -a -G group1 someuser

Это добавит пользователя группе group1.

Предоставление полномочий Sudo

После того как их учетная запись была создана, я предоставлю им очень конкретный sudo права (только если необходимый) использование visudo команда.

Посмотрите /etc/sudoers файл для большего количества информации о том, как предоставить определенные права. Не делайте этого:

someuser    ALL=(ALL)       ALL

если Вы не намереваетесь предоставить им полный корневой доступ к системе. Также думайте об установке периода времени, как долго учетная запись должна быть действительной. Вы могли бы хотеть установить тайм-аут на нем так, чтобы это было только допустимо для окна времени.

Если они должны просто работать date команда, например:

Cmnd_Alias DATE=/bin/date
ALL ALL=NOPASSWD: DATE   

Также Вы могли бы хотеть создать группы Unix на основе ролей, возможно myadmins & regusers. Затем используйте эти группы в Вашем sudoers файл при предоставлении доступа.

%myadmins   ALL=(ALL)       ALL
%regusers   ALL=(ALL)       DATE
3
24.06.2015, 14:02
5 ответов

Хотя на самом деле вы можете сделать это с Perl, синтаксис не самый простой (или, по крайней мере, не самый лучший, который я могу придумать). Вероятно, будет проще и быстрее использовать другие инструменты. Например,

  1. sed

  2. gawk (относительно недавние версии)

    for f в file*csv; do 
     ...на месте... Ф...
     если($1==FILENAME){print} else{print FILENAME", "$0}
     }' "$f"; 
    готово
    
2
27.01.2020, 21:10

Вот ваш однострочный файл perl: он работает с несколькими файловыми аргументами.

perl -i -pe '/^$ARGV,/ or print "$ARGV,"' file1 file2 ...

$ ARGV - это волшебная переменная, в которой хранится имя текущего файла. файл.
См. http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles

Разделитель полей (запятая) жестко запрограммирован. Вы можете решить, если это проблема.

Небольшое улучшение производительности:

perl -i -pe 'index($_, "$ARGV,") == 0 or print "$ARGV,"' file1 file2 ...
3
27.01.2020, 21:10

Невозможно управлять одним лайнером, но вот скрипт perl . Поместите его в файл и сделайте его исполняемым. Затем присвойте ему имена файлов *. Csv в качестве аргументов. Он создает *. New файлов. Если вы уверены, что это работает, раскомментируйте команду rename в конце.

#!/usr/bin/perl
use strict;
foreach my $file(@ARGV){
    open(F,$file) or die "$file:$!";
    $_ = <F>;
    next if $_=~/^$file,/;
    open(OUT,">$file.new") or die;
    my $add = "$file,";
    print OUT $add,$_;
    while(<F>){
        print OUT $add,$_;
    }
    close OUT;
    close F;
    #rename("$file.new","$file");
}
1
27.01.2020, 21:10

Прежде чем рассказывать о скорости Perl, попробуйте ускорить свой собственный скрипт

for f in *file*.csv;
do 
    sed -i "/^$f,/! s/^/$f,/" "$f"
done
2
27.01.2020, 21:10

Хорошо, проблема с «perl one liner», как вы заметили:

perl -p -i -e 's/^/Welcome to Hell,/' file*.csv

Это применяет преобразование к файлу достаточно правильно, но perl «обрабатывает» открытие файла (ов) и их потоковую передачу через STDIN автоматически. Это означает, что вы не знаете имя своего файла, когда делаете это.

Параметр на месте редактирования ( -i ) удобен, но на самом деле его сложнее использовать эффективно, поскольку вы потенциально открываете файл для чтения и записи. одновременно.

В любом случае, я бы подошел к вашей проблеме следующим образом:

#!/usr/bin/perl

use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new( { binary => 1 } );

foreach my $filename ( glob("*.csv") ) {
    open( my $output, ">", "new.$filename.csv" ) or warn $!;
    open( my $input, "<", "$filename.csv" ) or warn $!;
    while ( my $row = $csv->getline($input) ) {
        if ( not $row->[0] eq m/$filename/ ) {
            unshift( @{$row}, $filename );
        }
        $csv->print( $output, $row );
    }
}

Он использует модуль Text :: CSV , потому что на самом деле CSV часто сложнее, чем просто «разделение на запятую» (подумайте о нескольких строчные поля и запятые в тексте).

1
27.01.2020, 21:10

Теги

Похожие вопросы