Cómo agregar comillas dobles a la ruta del depósito s3 en un archivo .tsv usando sed/awk en bash shell

Cómo agregar comillas dobles a la ruta del depósito s3 en un archivo .tsv usando sed/awk en bash shell

Tengo .tsvun archivo que contiene la información de origen y destino del depósito s3. Estoy usando el bucle while para leer la ruta de origen y destino de ese archivo y realizar s3 cpla operación. Tenga en cuenta que el archivo contiene 100.000 líneas.

¿Cómo puedo utilizar el sedcomando para que todas las rutas de origen y destino estén entre comillas dobles dentro del archivo ( xx.tsv)? Necesito la comilla doble porque AWS S3 no puede manejar el nombre del archivo/carpeta que tiene espacios en blanco sin encerrarlos "".

Estoy buscando algo así como que se cambiarán las 3 líneas siguientes

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

a

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

Respuesta1

Usando cualquier awk en cualquier shell en cada caja Unix:

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

Lo anterior supone que ninguno de los nombres de sus archivos contiene tabulación, nueva línea o comillas dobles.

Respuesta2

$ 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

Nota: las columnas están separadas por un carácter de tabulación, no por varios espacios.

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

Usar \s+o [[:blank:]]+entre los dos grupos de captura en lugar de \ttambién funciona y produce resultados idénticos. es decir

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

y

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

La [[:blank:]]+versión coincidirá con uno o más caracteres de espacio o tabulación como separador de columnas, mientras que la \s+versión coincidirá con uno o más decualquiercarácter de espacio en blanco (que incluye espacios, tabulaciones y más).

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

Respuesta3

Tratar los datos como un archivo CSV que utiliza pestañas para delimitadores de campos:

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

Esto utiliza csvformatdesdecsvkitpara leer la entrada delimitada por tabulaciones ( -t) y produce una salida delimitada por tabulaciones ( -T) que se cita ( -U1) sin importar si el formato CSV lo requiere o no.

Tratar el archivo como un archivo CSV y utilizar un analizador CSV para realizar las citas por usted tiene la ventaja de no citar dos veces los campos si ya están citados.

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

Obviamente, también puede leer los datos tal como están y agregar las comillas dobles cuando llame s3 cp. No sé cómo se ve ese comando pero...

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

Respuesta4

Hay muchas formas de pelar esa papa, pero la mía sería

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

que utiliza sedpara aplicar una expresión regular en la entrada, capturando todas las partes de la cadena "no el espacio entre s3-URL" y luego poniéndolas entre comillas.

Espero que quien haya escrito las herramientas que generaron el .tsv aprenda algo de esto; esto también podría haber salido irremediablemente mal, si hubiera nuevas líneas en los nombres de los archivos, por ejemplo, lo cual es perfectamente legal para los nombres de los archivos (puede que no sea en S3, no lo he comprobado).

Almacenar nombres de archivos en archivos "cualquiera que sean los delimitados" terminará mal (a menos que ese delimitador sea de 0 bytes, que es prácticamente el único byte prohibido en los nombres de archivos). Necesita escapar, o mejor aún, no almacenar largas listas de nombres de archivos en archivos de texto, sino usar algo simple de usar como sqlite.

información relacionada