.tsv
s3バケットのソース情報とターゲット情報を含むファイルがあります。私はこのファイルからソースとターゲットのパスを読み込み、s3 cp
操作を実行するためにwhileループを使用しています。このファイルには100,000行が含まれています。
sed
コマンドを使用して、ファイル内のすべてのソースパスとターゲットパスを二重引用符()にする方法xx.tsv
。 aws s3では、スペースを含むファイル/フォルダ名を処理できないため、二重引用符が必要です""
。
変更する次の3行のようなものを探しています。
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
到着
"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"
答え1
すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ 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"
上記は、ファイル名にタブ、改行、または二重引用符が含まれていないと想定しています。
答え2
$ 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
注:列は複数のスペースではなくタブで区切られています。
そして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"
代わりに、2つのキャプチャグループ間でorを使用すると\s+
機能し、同じ出力が生成されます。今すぐ[[:blank:]]+
\t
sed -E 's/^(s3:.*)[[:blank:]]+(s3:.*)/"\1"\t"\2"/' input.tsv
そして
sed -E 's/^(s3:.*)\s+(s3:.*)/"\1"\t"\2"/' input.tsv
version は[[:blank:]]+
列区切り文字で 1 つ以上のスペースまたはタブと一致し、version は\s+
1 つ以上のスペースまたはタブと一致します。どのスペース文字(スペース、タブなどを含む)
そして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"
答え3
タブ文字をフィールド区切り文字として使用して、データをCSVファイルとして表示します。
csvformat -tT -U1 file.tsv >newfile.tsv
これはcsvformat
以下で使用されます。csvkitタブ区切り入力(-t
)を読み取り、タブ区切り出力()を生成します。これはCSV形式に必要かどうか-T
()に関係なく引用されます。-U1
ファイルをCSVファイルとして処理し、CSVパーサーを使用して引用を実行すると、フィールドがすでに参照されている場合は2回参照されないという利点があります。
$ 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"
明らかに、データを直接読み取って呼び出すときに二重引用符を追加することもできますs3 cp
。その命令がどんなものかはわかりませんが…
while IFS=$'\t' read -r src dst; do
s3 cp "\"$src\"" "\"$dst\""
done <file.tsv
答え4
ジャガイモの皮をむく方法はいくつかありますが、私の方法は
sed 's;^\(s3://.*\) \(s3://.*\)$;"\1" "\2";' filename_in.tsv > out.tsv
sed
入力に正規表現を適用し、s3-URL間の空白ではなく文字列のすべての部分をキャプチャし、引用符で囲むために使用されます。
.tsvを生成するツールを書いている人がこれから何かを学ぶことができることを願っています。たとえば、ファイル名に改行があると、回復不能なエラーが発生する可能性があります。これはファイル名に完全に適しています(S3では解決されていない可能性があります)。 )。
「区切り文字に関係なく」ファイルにファイル名を保存すると、結果が悪くなります(対応する区切り文字が0バイトの場合を除く)。これはファイル名でほとんど禁止されている唯一のバイトです。エスケープする必要があるか、より良い方法は、長いファイル名のリストをテキストファイルに保存するのではなく、単純なSQLiteを使用することです。