どのサーバーに特定のファイルと所有権があるかを知らせるcsvファイルを生成したいと思います。これは私が得る生の出力です。
server01,server02,server03,owner,/etc/file1
server04,owner,/etc/file2
server05,server06,owner,/etc/file3
サーバー名間のカンマをWindows形式の改行(CF + LR)に変更し、その間に引用符を追加して、CSVに同じボックスにすべてのサーバーを表示させたいと思います。
希望の出力:
"server01
server02
server03",owner,/etc/file1
"server04",owner,/etc/file2
"server05
server06",owner,/etc/file3
これを達成するためにsedを使用する方法は?
ベストアンサー1
,owner,
フィールドにラップする残りのテキストがすべてある場合:
GNUの使用sed
:
sed -E ':1; s/,(.*,owner,)/\r\n\1/; t1; s/(.*)(,owner,)/"\1"\2/' file
そしてperl
:
perl -pe 's{.*?(?=,owner,)}{q(") . ($& =~ s/,/\r\n/gr) . q(")}e' file
最後の2つのフィールドを除くすべての項目がある場合:
GNUの使用sed
:
sed -E ':1; s/(.*),(.*,.*,)/\1\r\n\2/; t1; s/(.*),/"\1",/' file
そしてperl
:
perl -pe 's{(.*)(?=,.*,)}{q(") . ($& =~ s/,/\r\n/gr) . q(")}e' file
または、Text::CSV
正しいCSVの解析とフォーマットのためにPerlモジュールを使用してください。
perl -MText::CSV -e '
$csv = Text::CSV->new({binary => 1, decode_utf8 => 0, eol => $" = "\r\n"});
while ($row = $csv->getline(STDIN)) {
if (($last = $#{$row}) > 1) {
$csv->print(STDOUT, ["@$row[0..$last-2]", @$row[$last-1..$last]]);
} else {
$csv->print(STDOUT, $row);
}
}' < file
ファイルがBOMでUTF-16またはUTF-8でエンコードされている場合(Microsoftファイルでは前例のない作業)、調整する必要があります(この方法については参考資料を参照)、何らかの方法でエンコードする必要があります。通常の入力を処理できるようにperldoc Text::CSV
フォーマットを再指定する方法です。<file dos2unix | ... | unix2dos