CSVファイルを処理するために1つのスクリプトに複数のsedコマンドを結合します


34

このようなCSVファイルを持っている:

HEADER
"first, column"|"second "some random quotes" column"|"third ol' column"
FOOTER

次のような結果を探します:

HEADER
first, column|second "some random quotes" column|third ol' column

言い換えると、「FOOTER」を削除すると、開始、終了、および前後に引用符が付きます。

これまでのところ、このコードは動作します:

sed '/FOOTER/d' csv > csv1 | #remove FOOTER
sed 's/^\"//' csv1 > csv2 | #remove quote at the beginning
sed 's/\"$//' csv2 > csv3 | #remove quote at the end
sed 's/\"|\"/|/g' csv3 > csv4 #remove quotes around pipe

あなたが問題を見るように、それは4つの余分なファイルを作成します。

余分なファイルを作成せず、1つのスクリプトで同じことを行うことを目標とする別のソリューションがあります。それはあまりうまくいきません。

#!/bin/ksh

sed '/begin/, /end/ { 
        /FOOTER/d
        s/^\"//
        s/\"$//
        s/\"|\"/|/g 
}' csv > csv4

1
引用符があるので、フィールドに改行を入れることができます。sed単純化されたcsvでのみ、あなたはそれで動作しません。実際のCSVファイル(Python / Perl / Ruby)を処理できるライブラリでプログラミング言語を使用します。
アントン

回答:


44

まず、マイケルが示したように、これらすべてを単一のコマンドに組み合わせることができます。

sed '/^FOOTER/d; s/^\"//; s/\"$//; s/\"|\"/|/g' csv > csv1

一部のsed実装ではこれに対処できず、次のものが必要になると思います。

  sed -e '/^FOOTER/d' -e 's/^\"//' -e 's/\"$//' -e 's/\"|\"/|/g' csv > csv1

とはいえ、フィールドはによって定義されているように見え、フィールド内のフィールドはそのままにして、フィールド全体|を削除"したいだけです。その場合、次のことができます。

$ sed '/FOOTER/d; s/\(^\||\)"/\1/g; s/"\($\||\)/\1/g' csv 
HEADER
first, column|second "some random quotes" column|third ol' column

または、GNUでsed

sed -r '/FOOTER/d; s/(^|\|)"/\1/g; s/"($|\|)/\1/g' csv 

Perlを使用することもできます。

$ perl -F"|" -lane 'next if /FOOTER/; s/^"|"$// for @F; print @F' csv 
HEADER
first, column|second some random quotes column|third ol' column

13

これも機能します:

sed 's / ^ "//; s /" | "/ | / g; s /" "$ /" /'

例:

$ echo '"this"|" and "ths""|" and "|" this 2"|" also "this", "thi", "and th""' | 
sed 's/^"//; s/"|"/|/g; s/""$/"/'
this| and "ths"| and | this 2| also "this", "thi", "and th"

かわいいバージョン

sed '
s/^"//
s/"|"/|/g
s/""$/"/
$d
'

1
これはフッターを扱いません。
テルドン

3
ただし、その内容に関係なく、最後の行は削除されます。がない場合FOOTER、必要なデータが削除されます。
テルドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.