入力(ソートされていない、不良)
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-44432"
,"XYZ-ZTE-43255"
"XYZ-ZTE-52775 serverB110 agreed",
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed",
"XYZ-ZTE-81422 - serverB609 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-32785 - serverA626 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed",
,"XYZ-ZTE-11591"
出力(並べ替え、必要な項目、良い項目!)
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-43255"
,"XYZ-ZTE-44432"
"XYZ-ZTE-52775 serverB110 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-81422 - serverB609 agreed",
"XYZ-ZTE-32785 - serverA626 agreed",
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed","XYZ-ZTE-11591"
簡単に言えば、これは2つの列を含むXLSの一部です。両方の列は、次の方法で一緒に整列する必要があります。
左の列の XYZ-ZTE-77323 は右の列の XYZ-ZTE-77323 と一致します。
しかし、次のようなものもあります。
,"XYZ-ZTE-43255"
これは次の行と一致する必要があります。
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-43255"
ただし、(入力の)行にはすでに正しい列が含まれています。
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-44432"
たとえば、次のような場合:
"XYZ-ZTE-44432"
左の列には存在しません。 OUTPUTの新しい行にする必要があります。
これを行う方法を知っている人はいますか?
答え1
私はこのプログラムを試しましたが、最高のプログラムではありませんが(ファイルを2回解析し、いくつかの重複したコードがあります)、必要に応じて自由に適用できます。うまくいくと思います。
$ cat script.pl
use warnings;
use strict;
use Text::CSV_XS;
my (%col1, %col2);
my $csv = Text::CSV_XS->new(
{ empty_is_undef => 1 }
) or die "Error: " . Text::CSV_XS->error_diag();
chomp( my @data = <STDIN> );
## Read file and save first column in %col1 hash and second
## column in %col2 hash.
foreach my $line ( @data ) {
die "Error in parse of CSV file\n" unless $csv->parse( $line );
my @columns = $csv->fields();
$col1{ $columns[0] }++ if defined $columns[0];
$col2{ $columns[1] }++ if defined $columns[1];
}
LINE:
foreach my $line ( @data ) {
die "Error in parse of CSV file\n" unless $csv->parse( $line );
my @columns = $csv->fields();
## Discard line if both columns are undefined.
next if !defined $columns[0] && !defined $columns[1];
## 1.- Undefined first column: Save second column in hash.
do { $col2{ $columns[1] } = 1; next } unless defined $columns[0];
## 2.- Both columns are defined: Sort them.
if ( defined $columns[0] && defined $columns[1] ) {
if ( index( $columns[0], $columns[1] ) > -1 ) {
# Line is sorted, print it.
print quote($columns[0]), ",", quote($columns[1]), "\n";
delete $col2{ $columns[1] };
} else {
# Line unsorted, search its equivalent in hash of second column
# and print.
my $key = $1 if $columns[0] =~ /^(\S*)/;
print quote($columns[0]), ",", ( exists $col2{ $key } ? quote($key) : "" ), "\n";
delete $col2{ $key } if exists $col2{ $key };
# Here, the second unsorted column, search its equivalent in first
# column. If not found print it now, else it will be printed later.
for my $str ( keys %col1 ) {
next LINE if index( $str, $columns[1] ) > -1;
}
print ",", quote($columns[1]), "\n";
}
next;
}
## 3.- Undefined second column: Check if second column is saved in
## hash and join it with first column.
unless ( defined $columns[1] ) {
my $key = $1 if $columns[0] =~ /^(\S*)/;
print quote($columns[0]), ",", ( exists $col2{ $key } ? quote($key) : "" ), "\n";
delete $col2{ $key } if exists $col2{ $key };
}
}
sub quote {
my ($str) = $_[0];
$str =~ s/^(.*)$/"$1"/;
return $str;
}
あなたのデータファイル:
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-44432"
,"XYZ-ZTE-43255"
"XYZ-ZTE-52775 serverB110 agreed",
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed",
"XYZ-ZTE-81422 - serverB609 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-32785 - serverA626 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed",
,"XYZ-ZTE-11591"
結果:
$ perl script.pl <yourdatafile
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-43255"
,"XYZ-ZTE-44432"
"XYZ-ZTE-52775 serverB110 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-81422 - serverB609 agreed",
"XYZ-ZTE-32785 - serverA626 agreed",
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed","XYZ-ZTE-11591"
答え2
データベースにデータを入力し、結合を使用して目的の基準に基づいてデータを取得します。 SQLiteはサーバーコンポーネントのない素晴らしい軽量システムで、このように小さなデータセットを操作するのに適しています。
答え3
これにより、Pythonを使用して予想される出力が生成されます。私はPytonがよくわからないので少しハッキング的ですが、動作します:)
#!/bin/bash
python -c '
import sys, csv;
reader = csv.reader(sys.stdin)
nbli=0 # line number (to maintin input order)
nbwi=6 # width of line number.. (zero padded)
left=[]
rght=[]
for row in reader:
nbli+=1
fnum=format(nbli, "0"+str(nbwi)+"d")
if row[0] != "": left.append(row[0]+fnum)
if row[1] != "": rght.append(row[1]+fnum)
left.sort()
rght.sort()
coll = []
l ,r = 0, 0
while l < len(left) or r < len(rght):
#
if l >= len(left):
numr = rght[r][-nbwi:]
datr = rght[r][:len(rght[r])-nbwi]
coll.append(numr + " " + ",\"" + datr + "\"")
r+=1
elif r >= len(rght):
numl = left[l][-nbwi:]
datl = left[l][:len(left[l])-nbwi]
coll.append(numl + " " + "\"" + datl + "\",")
l+=1
else:
numl = left[l][-nbwi:]
numr = rght[r][-nbwi:]
datl = left[l][:len(left[l])-nbwi]
datr = rght[r][:len(rght[r])-nbwi]
#
if datl.startswith(datr+" "):
coll.append(numl + " " + "\"" + datl + "\",\"" + datr + "\"")
l+=1
r+=1
elif datl < datr + " ":
coll.append(numl + " " + "\"" + datl + "\",")
l+=1
else:
coll.append(numr + " " + ",\"" + datr + "\"")
r+=1
coll.sort()
c = 0
while c < len(coll):
print coll[c][nbwi+1:]
c+=1
' \
<<-'STDIN'
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-44432"
,"XYZ-ZTE-43255"
"XYZ-ZTE-52775 serverB110 agreed",
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed",
"XYZ-ZTE-81422 - serverB609 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-32785 - serverA626 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed",
,"XYZ-ZTE-11591"
STDIN
出力:
"XYZ-ZTE-43255 serverB618 agreed","XYZ-ZTE-43255"
,"XYZ-ZTE-44432"
"XYZ-ZTE-52775 serverB110 agreed","XYZ-ZTE-52775"
"XYZ-ZTE-79213 - serverB688 agreed",
"XYZ-ZTE-77323 serverB617 agreed","XYZ-ZTE-77323"
"XYZ-ZTE-81422 - serverB609 agreed",
"XYZ-ZTE-32785 - serverA626 agreed",
"XYZ-ZTE-43235 - serverA605 disagreed (asdfjlasdj yxvv il lkyeas sadfa)","XYZ-ZTE-43235"
"XYZ-ZTE-11591 serverB144 agreed","XYZ-ZTE-11591"