filename~contenturl~uuid~nodeid~contentid
000224.pdf~store://2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin~d6203724-1100-4057-9ed5-4ca6a94f5512~1324625~1363256
000238.pdf~store://2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin~96b7343d-349d-4316-8bc6-def5bd924032~1324641~1363292
000262.pdf~store://2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin~11827eee-67bb-43b7-a743-966514f26457~1324661~1363375
上記は、区切り文字 "〜"を持つ.csvファイルです。 store://で始まる2番目の列の部分文字列を作成し、その行のチェックサム結果を同じ列に追加しようとしています。新しい列は、可能であればCSVを使用します。
例えば
filename~contenturl~checksum
000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 23423423425
したがって、最終結果が表示されたら、store://のパス部分文字列を作成し、そのファイルのチェックサムという新しい列を追加します。
シェルスクリプトでbin / bashを使用したい
========================私の場合は、今AWKを試してみましたが、次のようにして最初と2番目の列値のみを取得できました。
awk -F "~" '{print $1, $2}' $csv_file
今、次のタスクは複雑です。 2番目の列値にはテキスト処理が必要です。チェックサムあなたは合格できます
cksum /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin
はい、ちゃんと聞きました。最終結果は次のとおりです。
filename~contenturl~checksum
000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 23423423425
他の列の残りの部分もあれば良いでしょう。それ以外の場合は、上位3列も問題ありません。 注:既存の列を維持し、「チェックサム」という列を追加してもかまいません。
答え1
回避策を少し簡単にし、ヘッダー行が一貫していないため(入力ファイルの改行が間違っていて出力ファイルの区切り文字が間違っている~
)、入力ファイルにヘッダー行がないとしましょう。
これは次の2つのステップで解決できます。
ファイルを作成するには、
checksums.csv
ファイルパスだけが必要です。awk -F'~' '{ system("cksum /opt/xyz"substr($2,8)) }' file.csv > checksums.csv
substr($2,8)
プレフィックスを削除しstore:/
て/opt/xyz
前に追加してパスを完成させます。このsystem(…)
コマンドは、指定されたパスでコマンドを実行し、cksum
出力を出力ファイルにリダイレクトします。サンプル出力は次のとおりです。
$ cat checksums.csv 128361894 41 /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 820470222 41 /opt/xyz/2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin 1593587341 41 /opt/xyz/2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin
出力にはチェックサム、バイト数、パスの3つの列が含まれているため、次のステップで3番目と1番目の列を抽出する必要があります。
ヘッダー行を印刷し、列1(ファイル名)を
file.csv
列3(パス)および列1(チェックサム)とマージしますchecksums.csv
。{ echo "filename contenturl checksum";\ paste -d ' ' <(awk -F'~' '{ print $1 }' file.csv) <(awk '{ print $3,$1 }' checksums.csv);\ } > newfile.csv
出力例:
$ cat newfile.csv filename contenturl checksum 000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 128361894 000238.pdf /opt/xyz/2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin 820470222 000262.pdf /opt/xyz/2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin 1593587341
その後、クリーンアップします。
rm checksums.csv
答え2
GNUには、スクリプトのようにシェル処理を統合するためのコマンドフラグがsed
あります。e
s
cksum
sed -E 'h;s_.*~store:/([^~]*).*_cksum /opt/xyz\1_e;x;G;s_~[^~]*(.*)\n(.*) .* (.*)_~\2~\3\1_;s/~/ /g'
-E
読みやすくするために拡張正規表現に切り替えるオプションh
現在行を予約済みスペースに保存して、必要に応じて処理できます。s_.*~store:/([^~]*).*_cksum /opt/xyz\1_e
store:/
(削除する)、()
再利用するファイル名\1
、残りの行(削除する)を含むすべての項目を一致させ、cksum
+パスに置き換えます。フラグはe
このコマンドを実行し、パターンスペースを返された内容に置き換え始めます。x;G
ホールドスペースとパターンスペースを変更し、パターンスペースにホールドを追加してバッファに次のものを含めます。s_~[^~]*(.*)\n(.*) .* (.*)_~\2~\3\1_
読む必要があるかもしれませんが、書き込みが簡単です。~[^~]*
2番目のフィールド、(.*)\n
元の行の残りの部分、(.*) .* (.*)
3つのフィールドが返されるので、cksum
2番目のフィールドはファイル名とチェックサムに置き換えられます。- 質問に書きませんでしたが、例には
~
区切り文字はありませんが、2つのスペースがあります。s/~/ /g