Verbinden Sie mehrere sed-Befehle in einem Skript, um die CSV-Datei zu verarbeiten


34

Eine CSV-Datei wie diese haben:

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

und auf der Suche nach Ergebnis wie:

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

mit anderen Worten: Entfernen von "FOOTER", Anführungszeichen am Anfang, Ende und um |.

Bisher funktioniert dieser Code:

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

Wie Sie sehen, werden 4 zusätzliche Dateien erstellt.

Hier ist eine andere Lösung, die das Ziel hat, keine zusätzlichen Dateien zu erstellen und dasselbe in einem einzigen Skript zu tun. Das funktioniert nicht sehr gut.

#!/bin/ksh

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

1
Da Sie Anführungszeichen haben, können Sie Zeilenumbrüche in den Feldern haben. du sedwirst damit nicht arbeiten, nur mit vereinfachtem csv. Verwenden Sie eine Programmiersprache mit einer Bibliothek, die echte CSV-Dateien verarbeiten kann (Python / Perl / Ruby).
Anthon

Antworten:


44

Erstens, wie Michael gezeigt hat, können Sie all diese Befehle einfach zu einem einzigen Befehl kombinieren:

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

Ich denke, einige sedImplementierungen kommen damit nicht klar und benötigen möglicherweise:

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

Das heißt, es sieht so aus, als wären Ihre Felder durch definiert, |und Sie möchten nur "das gesamte Feld entfernen und die Felder im Feld belassen. In diesem Fall können Sie Folgendes tun:

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

Oder mit GNU sed:

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

Sie könnten auch Perl verwenden:

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

13

Das würde auch funktionieren:

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

Beispiel:

$ 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"

hübsche Version

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

1
Dies betrifft nicht die Fußzeile.
Terdon

3
Dadurch wird jedoch die letzte Zeile unabhängig vom Inhalt entfernt. Wenn dies nicht der Fall ist FOOTER, werden die gewünschten Daten entfernt.
terdon
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.