So fügen Sie mit sed/awk in der Bash-Shell doppelte Anführungszeichen zum S3-Bucket-Pfad in einer TSV-Datei hinzu

So fügen Sie mit sed/awk in der Bash-Shell doppelte Anführungszeichen zum S3-Bucket-Pfad in einer TSV-Datei hinzu

Ich habe .tsveine Datei, die die Quell- und Zielinformationen des S3-Buckets enthält. Ich verwende eine While-Schleife, um den Quell- und Zielpfad aus dieser Datei zu lesen und den s3 cpVorgang auszuführen. Bitte beachten Sie, dass die Datei 100.000 Zeilen enthält.

Wie kann ich den Befehl so verwenden, seddass alle Quell- und Zielpfade in der Datei in doppelte Anführungszeichen gesetzt werden ( xx.tsv). Ich brauche die doppelten Anführungszeichen, weil AWS S3 Datei-/Ordnernamen mit Leerzeichen nicht verarbeiten kann, ohne sie in Anführungszeichen einzuschließen "".

Ich suche etwas wie unten 3 Zeilen werden geändert

s3://data01/repo01/image live01.png s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png s3://Ata03/vol01/image live01.png

Zu

"s3://data01/repo01/image live01.png" "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png" "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png" "s3://Ata03/vol01/image live01.png"

Antwort1

Verwenden eines beliebigen awk in einer beliebigen Shell auf jeder Unix-Box:

$ awk -F'\t' -v OFS='"\t"' '{print "\"" $1, $2 "\""}' file
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

Das Obige setzt voraus, dass keiner Ihrer Dateinamen Tabulatoren, Zeilenumbrüche oder Anführungszeichen enthält.

Antwort2

$ cat input.tsv 
s3://data01/repo01/image live01.png     s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png     s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png     s3://Ata03/vol01/image live01.png

Hinweis: Die Spalten sind durch ein Tabulatorzeichen und nicht durch mehrere Leerzeichen getrennt.

Mit sed:

$ sed -E 's/^(s3:.*)\t+(s3:.*)/"\1"\t"\2"/' input.tsv 
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

Die Verwendung von \s+oder [[:blank:]]+zwischen den beiden Erfassungsgruppen anstelle von \tfunktioniert ebenfalls und erzeugt eine identische Ausgabe. d. h.

sed -E 's/^(s3:.*)[[:blank:]]+(s3:.*)/"\1"\t"\2"/' input.tsv

Und

sed -E 's/^(s3:.*)\s+(s3:.*)/"\1"\t"\2"/' input.tsv

Die [[:blank:]]+Version entspricht einem oder mehreren Leerzeichen oder Tabulatorzeichen als Spaltentrennzeichen, während die \s+Version einem oder mehreren entsprichtbeliebigLeerzeichen (darunter Leerzeichen, Tabulatoren und mehr).

mit awk:

$ awk -F'\t' '{print "\"" $1 "\"\t\"" $2 "\""}' input.tsv 
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

Antwort3

Behandeln der Daten als CSV-Datei, die Tabulatoren als Feldtrennzeichen verwendet:

csvformat -tT -U1 file.tsv >newfile.tsv

Dies nutzt csvformatvoncsvkitum die tabulatorgetrennte Eingabe ( -t) zu lesen und eine tabulatorgetrennte Ausgabe ( -T) zu erzeugen, die in Anführungszeichen ( -U1) steht, unabhängig davon, ob das CSV-Format dies erfordert oder nicht.

Wenn Sie die Datei als CSV-Datei behandeln und einen CSV-Parser zum Setzen von Anführungszeichen verwenden, haben Sie den Vorteil, dass Felder nicht doppelt in Anführungszeichen gesetzt werden, wenn sie bereits in Anführungszeichen gesetzt sind.

$ cat file.tsv
"s3://data01/repo01/image live01.png"   s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png     s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png     s3://Ata03/vol01/image live01.png
$ csvformat -tT -U1 file.tsv
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

Sie können die Daten natürlich auch einfach so lesen, wie sie sind, und beim Aufruf die Anführungszeichen hinzufügen s3 cp. Ich weiß nicht, wie dieser Befehl aussieht, aber ...

while IFS=$'\t' read -r src dst; do
    s3 cp "\"$src\"" "\"$dst\""
done <file.tsv

Antwort4

Es gibt viele Möglichkeiten, diese Kartoffel zu schälen, aber meine wäre

sed 's;^\(s3://.*\) \(s3://.*\)$;"\1" "\2";' filename_in.tsv > out.tsv

Dabei wird sedein regulärer Ausdruck auf die Eingabe angewendet, wobei alle Teile der Zeichenfolge „außer dem Leerzeichen zwischen S3-URLs“ erfasst und dann in Anführungszeichen gesetzt werden.

Ich hoffe, dass derjenige, der die Tools geschrieben hat, mit denen die TSV-Datei generiert wurde, daraus etwas lernt. Es hätte auch irreparabel schiefgehen können, wenn die Dateinamen beispielsweise Zeilenumbrüche enthielten, was bei Dateinamen völlig zulässig ist (ist bei S3 möglicherweise nicht der Fall, habe es nicht überprüft).

Das Speichern von Dateinamen in Dateien mit „beliebigen Trennzeichen“ wird böse enden (es sei denn, das Trennzeichen ist ein 0-Byte, was so ziemlich das einzige verbotene Byte in Dateinamen ist). Sie müssen maskieren oder, noch besser, speichern Sie keine langen Listen von Dateinamen in Textdateien, sondern verwenden Sie etwas Einfaches, das sich als SQLite verwenden lässt.

verwandte Informationen