সেড বা অ্যাজকের সাহায্যে কীভাবে কোনও সিএসভি ফাইল ম্যানিপুলেট করবেন?


23

আমি কীভাবে সিএসভি ফাইলটিতে নিম্নলিখিতটি ব্যবহার করতে পারি sedবা ব্যবহার করতে পারি awk?

  • একটি কলাম মুছুন
  • একটি কলাম সদৃশ
  • একটি কলাম সরান

আমার 200 টিরও বেশি সারির একটি বড় টেবিল রয়েছে এবং আমি এর সাথে পরিচিত নই sed


1
ক্রস আস্কউবুন্টুতে পোস্ট করেছেন
enzotib

@ এঞ্জোটিব আপনি কি লিঙ্কটি পোস্ট করতে পারবেন?
n0pe

@ ম্যাক্সম্যাকি জিজ্ঞাসুবুন্টু / প্রশ্ন / 88142 /… । আমি এই মুহুর্তে সেখানে একটি মোডের জমি পেতে পারি না, তাই আমি যদি তাদের ইচ্ছুক হয় তবে তারা স্থানান্তর করতে বলার জন্য পতাকাঙ্কিত করেছি; এর ইতিমধ্যে একটি স্বীকৃত উত্তর রয়েছে সুতরাং তারা নিশ্চিত কিনা তা আমি নিশ্চিত নই
মাইকেল মরোজেক

@ মিশেলমরোজেক, এইচএমএম এই পরিস্থিতিতে সাধারণত কি হয়? আমরা কি কেবল নকলগুলি রাখি?
n0pe

1
আপনার যদি এমন কোনও সিস্টেমে চালনার দরকার না হয় যেখানে কেবলমাত্র মৌলিক সরঞ্জাম উপলব্ধ রয়েছে, দেখুন সিএসভি ফাইলগুলি প্রক্রিয়াকরণের জন্য একটি শক্তিশালী কমান্ড লাইন সরঞ্জাম আছে?
গিলস 'অশুভ হওয়া বন্ধ করুন'

উত্তর:


7

ক্ষেত্রগুলি কীভাবে কাটা এবং পুনঃব্যবস্থা করা যায় তা বাদ দিয়ে (অন্যান্য উত্তরে coveredাকা) স্নিগ্ধ সিএসভি ক্ষেত্রের সমস্যা রয়েছে।

যদি আপনার ডেটা এই "উদ্দীপনা" বিভাগে চলে আসে তবে কিছুটা পূর্ব এবং পোস্ট ফিল্টারিং এটি যত্ন নিতে পারে। নিচে দেখানো ফিল্টার প্রয়োজন অক্ষর \x01, \x02, \x03, \x04আপনার ডেটা কোন জায়গায় প্রদর্শিত হবে না হবে।

সাধারণ awkফিল্ড ডাম্পের চারপাশে জড়িত ফিল্টারগুলি এখানে ।

দ্রষ্টব্য: ফিল্ড-ফাইভের একটি অবৈধ / অসম্পূর্ণ "উদ্ধৃত ক্ষেত্র" বিন্যাস রয়েছে, তবে এটি একটি সারির শেষে (সিএসভি পার্সারের উপর নির্ভর করে) সৌম্য। তবে এটি অবশ্যই সমস্যাবহির্ভূত ফলাফলের কারণ হতে পারে যদি এটি তার বর্তমান প্রান্তের সারি অবস্থান থেকে সরে যেতে হয় ।

হালনাগাদ; ব্যবহারকারী 121196 যখন একটি কমা একটি পূর্ববর্তী উদ্ধৃতিটির পূর্বে একটি বাগ নির্দেশ করেছে pointed এখানে ঠিক আছে।

তথ্যটি

cat <<'EOF' >file
field one,"fie,ld,two",field"three","field,\",four","field,five
"15111 N. Hayden Rd., Ste 160,",""
EOF

কোড

sed -r 's/^/,/; s/\\"/\x01/g; s/,"([^"]*)"/,\x02\1\x03/g; s/,"/,\x02/; :MC; s/\x02([^\x03]*),([^\x03]*)/\x02\1\x04\2/g; tMC; s/^,// ' file |
  awk -F, '{ for(i=1; i<=NF; i++) printf "%s\n", $i; print NL}' |
    sed -r 's/\x01/\\"/g; s/(\x02|\x03)/"/g; s/\x04/,/g' 

আউটপুট:

field one
"fie,ld,two"
field"three"
"field,\",four"
"field,five

"15111 N. Hayden Rd., Ste 160,"
""

এখানে প্রাক ফিল্টার , মন্তব্য সহ প্রসারিত। পোস্ট ফিল্টার মাত্র একটি উলটাপালটা হয় । , ,
\x01\x02\x03\x04

sed -r '
    s/^/,/                # add a leading comma delimiter
    s/\\"/\x01/g          # obfuscate escaped quotation-mark (\")
    s/,"([^"]*)"/,\x02\1\x03/g    # obfuscate quotation-marks
    s/,"/,\x02/           # when no trailing quote on last field  
    :MC                   # obfuscate commas embedded in quotes
    s/\x02([^\x03]*),([^\x03]*)/\x02\1\x04\2/g
    tMC
    s/^,//                # remove spurious leading delimiter
'

আপনি কীভাবে এই ফিল্টারটির উপর ভিত্তি করে নবম কলামটি মুছবেন?
ব্যবহারকারী 121196

@ ব্যবহারকারী 121196 - যেমনটির প্রথম বাক্যে উল্লিখিত হয়েছে, এই উত্তরটি সিএসভি ডেটা আরও সুসংগত করার একটি উপায় দেখায় .. যেমন। অস্থায়ীভাবে একটি নিরপেক্ষ টোকেন চরিত্রের সাথে কোট-এম্বেড থাকা কমাটি প্রতিস্থাপন করে ... এবং তারপরে মুছে ফেলা / কাট / মুছার পরে এটিকে আবার কমাতে ফিরিয়ে দেওয়া । আবার যেমনটি উল্লিখিত হয়েছে, সরানো / কাটা / মুছুন পদক্ষেপটি একটি সরল বিশ্রী ফিল্ড-ডাম্প দ্বারা প্রতিস্থাপিত হয় ।
পিটার.ও

1
এটি এই ক্ষেত্রে ব্যর্থ: "15111 এন। হেডেন আরডি।, স্টি 160,", ""
ব্যবহারকারী 121196

@ ব্যবহারকারী 121196: এটি নির্দেশ করার জন্য ধন্যবাদ। উত্তরটি আমি ঠিক করে আপডেট করেছি updated
পিটার.ও

15

এটি আপনার সিএসভি ফাইলটি কেবলমাত্র সীমানারদের জন্য কমা ব্যবহার করে বা আপনার মতো পাগলামি রয়েছে কিনা তার উপর নির্ভর করে:

ক্ষেত্র এক, "ক্ষেত্র, দুই", ক্ষেত্র তিন

এটি ধরে নিয়েছে যে আপনি একটি সাধারণ সিএসভি ফাইল ব্যবহার করছেন:

একটি কলাম সরানো হচ্ছে

আপনি একক কলাম থেকে বহু উপায়ে মুক্তি পেতে পারেন; উদাহরণ হিসাবে আমি কলাম 2 ব্যবহার করেছি। সম্ভবত সবচেয়ে সহজ উপায় হ'ল ব্যবহার করা cut, যা আপনাকে একটি ডিলিমিটার নির্দিষ্ট করতে দেয় -dএবং কোন ক্ষেত্রগুলি আপনি মুদ্রণ করতে চান -f; এটি এটিকে কমা ও আউটপুট ফিল্ড 1 এবং শেষের মধ্যে 3 দিয়ে বিভক্ত করতে বলে:

$ cut -d, -f1,3- /path/to/your/file

যদি আপনার আসলে ব্যবহারের প্রয়োজন হয় তবে আপনি sedএকটি নিয়মিত অভিব্যক্তি লিখতে পারেন যা প্রথম n-1ক্ষেত্র, nতম ক্ষেত্র এবং বাকী অংশগুলির সাথে মিলে যায় এবং আউটপুট এড়িয়ে যায় n(এখানে n2 রয়েছে, সুতরাং প্রথম গ্রুপটি 1সময়ের সাথে মিলেছে \{1\}:):

$ sed 's/\(\([^,]\+,\)\{1\}\)[^,]\+,\(.*\)/\1\3/' /path/to/your/file

এটি করার জন্য বেশ কয়েকটি উপায় রয়েছে awk, তাদের মধ্যে কোনওটি বিশেষভাবে মার্জিত নয়। আপনি একটি forলুপ ব্যবহার করতে পারেন , তবে পিছনের কমা নিয়ে কাজ করা একটি ব্যথা; এটি এমন কিছু হতে চাই তা উপেক্ষা করে:

$ awk -F, '{for(i=1; i<=NF; i++) if(i != 2) printf "%s,", $i; print NL}' /path/to/your/file

ক্ষেত্র 1 আউটপুট করা আমার পক্ষে আরও সহজ মনে হয়েছে এবং তারপরে substrফিল্ড 2 এর পরে সমস্ত কিছু বন্ধ করতে ব্যবহার করুন :

$ awk -F, '{print $1 "," substr($0, length($1)+length($2)+3)}' /path/to/your/file

এটি পাশাপাশি কলামগুলির জন্য বিরক্তিকর

একটি কলাম সদৃশ

এটিতে sedমূলত পূর্বের মত একই অভিব্যক্তি, তবে আপনি লক্ষ্য কলামটিও ক্যাপচার করেন এবং প্রতিস্থাপনে সেই গোষ্ঠীকে একাধিকবার অন্তর্ভুক্ত করেন:

$ sed 's/\(\([^,]\+,\)\{1\}\)\([^,]\+,\)\(.*\)/\1\3\3\4/' /path/to/your/file

ইন awkলুপ উপায় এটা পছন্দ (আবার চিহ্ন কমা উপেক্ষা) কিছু হতে চাই:

$ awk -F, '{
for(i=1; i<=NF; i++) {
    if(i == 2) printf "%s,", $i;
    printf "%s,", $i
}
print NL
}' /path/to/your/file

substrপথ:

$ awk -F, '{print $1 "," $2 "," substr($0, length($1)+2)}' /path/to/your/file

(tcdyl তার উত্তরে আরও ভাল পদ্ধতি নিয়ে এসেছিল )

একটি কলাম সরানো হচ্ছে

আমি মনে করি sedসমাধানটি অন্যদের থেকে স্বাভাবিকভাবে অনুসরণ করা হয় তবে এটি হাস্যকরভাবে দীর্ঘ হতে শুরু করে


এটাই বোঝা উত্তর! +1 :)
জয়পাল সিং

হাস্যকরভাবে দীর্ঘ? পাহ !
গিলস 'অশুভ হওয়া বন্ধ করুন'

12

awkআপনার সেরা বাজি awkসংখ্যা দ্বারা ক্ষেত্রগুলি মুদ্রণ করে, তাই ...

awk 'BEGIN { FS=","; OFS=","; } {print $1,$2,$3}' file

একটি কলাম মুছে ফেলতে, এটি মুদ্রণ করবেন না:

 awk 'BEGIN { FS=","; OFS=","; } {print $1,$3}' file

অর্ডার পরিবর্তন করতে:

awk 'BEGIN { FS=","; OFS=","; } {print $3,$1,$2}' file

একটি আউটপুট ফাইলে পুনর্নির্দেশ করুন।

awk 'BEGIN { FS=","; OFS=","; } {print $3,$1,$2}' file > output.file

awk আউটপুট পাশাপাশি বিন্যাস করতে পারেন।

ওহ ফরমেট আউটপুট


যেহেতু এটি সিএসভি, আপনারও দরকার BEGIN { FS=","; OFS=","; }

1
আমি মনে করি এমনকি এফএস = অফস = "," কাজ করবে।

5

নিম্নলিখিত বিন্যাসে একটি স্থান-সীমিত ফাইল দেওয়া হয়েছে:

1 2 3 4 5

আপনি যেমন ফিল্ড 2 মুছে ফেলাতে পারেন তেমন:

awk '{ sub($2,""); print}' file

যা ফিরে আসে

1  3 4 5

কলাম 2 যথাযথ যেখানে কলাম এন সাথে প্রতিস্থাপন করুন।

কলাম 2 নকল করতে,

awk '{ col = $2 " " $2; $2 = col; print }' file

যা ফিরে আসে

1 2 2 3 4 5

2 এবং 3 কলামটি স্যুইচ করতে,

awk '{temp = $2; $2 = $3; $3 = temp; print}'

যা ফিরে আসে

1 3 2 4 5

ক্ষেত্রের ধারণাটি মোকাবেলায় অ্যাডাব্লিকেশন সাধারণত খুব ভাল । যদি আপনি কোনও সিএসভি নিয়ে কাজ করে থাকেন, এবং কোনও স্থান-সীমিত ফাইল নয়, আপনি কেবল ব্যবহার করতে পারেন

awk -F,

আপনার ক্ষেত্রকে কমা হিসাবে পরিবর্তনের জন্য একটি স্থানের পরিবর্তে (যা পূর্বনির্ধারিত)। অনলাইনে বেশ কয়েকটি ভাল অ্যাডকো রিসোর্স রয়েছে যার মধ্যে একটির নীচে উত্স হিসাবে আমি তালিকাবদ্ধ করেছি।

# 3 এর জন্য উত্স


আমি এ সম্পর্কে তেমন কিছুই জানি না awk, তবে ক্ষেত্র বিভাজক হওয়া সত্ত্বেও এটি স্পেস-বিভাজিত বলে মনে হচ্ছে ,(ক্ষেত্র-বিভাজক কেবল এটি কীভাবে ইনপুট পরিচালনা করে)
মাইকেল মরোজেক

@ মিশেলমরোজেক: হ্যাঁ, এটি অফস অব ভেরিয়েবল যা আউটপুট ফিল্ড বিভাজককে নিয়ন্ত্রণ করে।
enzotib

হ্যাঁ, এবং আমি আমার উত্তরে উল্লেখ করেছি, আপনি ডিলিমিটারটি পরিবর্তন করার জন্য -F বিকল্পটি পাস করতে পারেন (যেমন
-এফ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.