![AWK를 사용하여 디렉토리 목록 조작](https://linux55.com/image/160998/AWK%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%20%EB%AA%A9%EB%A1%9D%20%EC%A1%B0%EC%9E%91.png)
디렉토리의 파일에서 mysql 삽입 스크립트를 작성하고 싶습니다.
별칭이 있어요v ='ls -l --time-style=+"%Y-%m-%d %H:%M:%S"'
디렉토리에는 약 1000개의 파일이 있으며 *.afl
awk 명령으로 작성된 스크립트를 사용하여 이 파일을 추출하고 테이블에 저장하려고 합니다.
ls -1 *.afl| here="$(cygpath -w $PWD)" awk -v source="$source" '{print "INSERT INTO action_diary (entry_date, entry_description,entry_details) VALUES (STR_TO_DATE(<FILE CREATION DATE>,\x27%Y-%m-%d\x27),,\x27\x27,\x27)" "File Name: "$0"\n"ENVIRON["here"]"\n"source"\x27"}'
다음 줄을 만듭니다.
INSERT INTO action_diary (entry_date, entry_description,entry_details) VALUES (STR_TO_DATE(<FILE CREATION DATE>,'%Y-%m-%d'),'','File Name: 2011 02 21 drdttl.afl
C:\Users\athena\Downloads\Project_1\00.MBT
Source: Parallel action
파일 타임스탬프가 포함되기를 원하기 때문에 여기에 갇혔습니다. 즉, ls -1을 사용할 수 없다는 뜻입니다.
나의 지식의 깊이가 바닥을 쳤습니다.
능숙한 사용자를 위한 팁이 있나요?
내가 사용한 답변
stat -c '%y %n' *.afl| here="$(cygpath -w $PWD)" awk -v source="$source" '{print "INSERT INTO action_diary (entry_date, entry_description,entry_details) VALUES (STR_TO_DATE(\x27"substr($0,1,18)"\x27,\x27%Y-%m-%d\x27),\x27\x27,\x27File Name: "substr($0,37)"\n"ENVIRON["here"]"\n"source"\x27"}'
답변1
이 작업을 수행하려면 다음과 같은 이유로 awk 대신 Perl을 사용합니다.
Perl은 디렉토리 내용 자체를 읽을 수 있습니다
readdir()
stat()
Perl에는 stat 명령과 유사한 기능을 가진 내장 함수가 있습니다 .날짜와 시간 형식을 지정하는 아주 좋은 Date::Format 모듈도 있습니다.
Perl에는 데이터베이스와 직접 상호 작용하는(예: mysql 자체에 레코드 삽입) DBI, DBD 및 DBD::mysql 모듈도 있습니다.
?
DBI 준비 문의 자리 표시자모두SQL 명령 문자열에서 이스케이프 및 인용 변수를 사용하는 수고를 없애세요.하나의 스크립트로 모든 작업을 수행할 수 있으며 쉘 참조를 처리하거나 환경 변수를 awk에 전달하는 것보다 훨씬 덜 번거롭습니다.
#!/usr/bin/perl
use strict;
use Date::Format;
use DBI;
# Fill in your database details here.
my $database='';
my $hostname='';
my $port='';
my $user='';
my $password='';
# set up connection to database.
my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
my $dbh = DBI->connect($dsn, $user, $password);
# set up sql statement
my $sth = $dbh->prepare('INSERT INTO action_diary (entry_date, entry_description, entry_details) VALUES (?,?,?)');
use Cwd;
my $cwd = getcwd;
# 'source' must be exported from the parent environment.
# alternatively, pass it as a command-line arg and read it from, e.g., $ARGV[0]
my $source=$ENV{'source'};
# find all .afl files in current dir, store with ctime in %files hash
# use `(stat($_))[9]` if you want the file's mtime rather than ctime.
opendir(DIR, '.') || die "Can't opendir .: $!\n";
foreach (readdir(DIR)) {
next unless (-f "./$_" && m/\.afl$/);
$files{$_} = (stat($_))[10];
};
closedir(DIR);
# sort the hash by value (timestamp)
foreach my $f (sort { $files{$a} <=> $files{$b} } keys %files) {
my $Y = time2str('%Y',$files{$f});
my $M = time2str('%m',$files{$f});
my $D = time2str('%d',$files{$f});
my $YMD = "$Y-$M-$D";
my $details = "File Name: $Y $M $D $f\n$cwd\n$source";
$sth->execute($YMD,'',$details);
}
$sth->finish();
$dbh->disconnect();
스크립트가 파일에 저장하거나 mysql로 파이프할 수 있는 일련의 SQL 문을 출력하도록 하려면 훨씬 더 간단합니다.
#!/usr/bin/perl
use strict;
use Date::Format;
use Cwd;
my $cwd = getcwd;
# 'source' must be exported from the parent environment.
# alternatively, pass it as a command-line arg and read it from, e.g., $ARGV[0]
my $source=$ENV{'source'};
# find all .afl files in current dir, store with ctime in %files hash
# use `(stat($_))[9]` if you want the file's mtime rather than ctime.
my %files=();
opendir(DIR, '.') || die "Can't opendir .: $!\n";
foreach (readdir(DIR)) {
next unless (-f "./$_" && m/\.afl$/);
$files{$_} = (stat($_))[10];
};
closedir(DIR);
my $FMT="INSERT INTO action_diary (entry_date, entry_description, entry_details) VALUES ('%s','%s','%s')\n";
# sort the hash by value (timestamp)
foreach my $f (sort { $files{$a} <=> $files{$b} } keys %files) {
my $Y = time2str('%Y',$files{$f});
my $M = time2str('%m',$files{$f});
my $D = time2str('%d',$files{$f});
my $YMD = "$Y-$M-$D";
my $details = "File Name: $Y $M $D $f\n$cwd\n$source";
# backslash-escape any quotes that may be in $details (i.e. from $f or $source).
# NOTE: very primitive. There are lots more characters that might need escaping
# or special handling than just a single-quote.
$details =~ s/'/\\'/g;
printf $FMT, $YMD,'',$details;
}
답변2
다음 추천을 사용하세요.무루
stat -c '%y %n' *.afl| here="$(cygpath -w $PWD)" awk -v source="$source" '{print "INSERT INTO activity_diary (entry_date, entry_description, entry_details) VALUES (STR_TO_DATE(\x27"substr($0,1,19)"\x27,\x27%Y-%m-%d\x27),,\x27Monitoring Log\x27,\x27" "File Name: "substr($0,37)"\nFile Location: "ENVIRON["here"]"\n"source"\x27)"}' >> new_activity_data.sql