AWKを使用したディレクトリリストの操作

AWKを使用したディレクトリリストの操作

ディレクトリ内のファイルからmysql挿入スクリプトを作成したいと思います。

エイリアスがあります。v ='ls -l --time-style=+"%Y-%m-%d %H:%M:%S"'

ディレクトリには約1000個のファイルがあり、*.aflawkコマンドで作成されたスクリプトを使用してこのファイルを抽出してテーブルに保存しようとしています。

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コマンド文字列でエスケープ変数と引用変数を使用する手間を省きます。

  • 1つのスクリプトですべての操作を実行でき、シェル参照を処理したり、環境変数を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;

}

おすすめ記事