কাটা ব্যবহার করে কলামগুলি পুনরায় সাজান


135

আমি নিম্নলিখিত বিন্যাসে একটি ফাইল করছি

কলাম 1 কলাম 2
str1 1
str2 2
str3 3

আমি কলামগুলি পুনরায় সাজানো চাই। কমান্ডের নীচে চেষ্টা করেছি

কাটা -f2,1 file.txt

কমান্ডটি কলামগুলি পুনরায় অর্ডার করে না। কোন ধারণা কেন এটি কাজ করে না?

ধন্যবাদ.

উত্তর:


148

জন্য cut(1)man পৃষ্ঠা:

একটি, এবং -b, -c বা -f এর মধ্যে একটি ব্যবহার করুন। প্রতিটি লিস্ট একটি রেঞ্জ বা বহু রেঞ্জকে কমা দ্বারা পৃথক করে তৈরি। নির্বাচিত ইনপুট একই ক্রমে লেখা হয় যা এটি পড়ে এবং ঠিক একবার লেখা হয়।

এটি প্রথমে 1 ফিল্ডে পৌঁছে যায়, তাই এটি মুদ্রিত হয়, ক্ষেত্র 2 পরে 2

awkপরিবর্তে ব্যবহার করুন:

awk '{ print $2 " " $1}' file.txt

12
এটি খুব খারাপ cutএই স্বজ্ঞাত পুনরায় ক্রম আদেশটি সমর্থন করে না। যাই হোক, অন্য টিপ: আপনি ব্যবহার করতে পারেন awk'র -FSএবং -OFSঅপশন ব্যবহার কাস্টম ইনপুট এবং আউটপুট ক্ষেত্র বিভাজক (যেমন -dএবং --output-delimiterজন্য cut)।
মালানা

12
দুঃখিত, FSএকটি বিকল্প, OFSএকটি পরিবর্তনশীল। যেমনawk -v OFS=";" -F"\t" '{print $2,$1}'
মালানা

2
গিট বাশের উইন্ডোজ ব্যবহারকারীদের জন্য নোট: আপনার যদি উপরের কমান্ডটি থেকে অদ্ভুত আউটপুট থাকে, কলামগুলি একে অপরকে ছাপিয়ে দেখার মতো হয়, তবে গাড়ীর ফেরত দোষারোপ। আপনার ফাইলের EOL সিআরএলএফ থেকে এলএফ এ পরিবর্তন করুন।
jakub.g

1
বিকল্প হিসাবে আপনি যদি ইনপুট ফাইলটি পরিবর্তন করতে না চান তবে আপনি পাইপ | sed 's/\r//' | দেওয়ার আগে এটি পাইপ করতে পারেনawk
jakub.g

2
এটি একটি খুব সহজ তবে কারও পক্ষে কার্যকর হতে পারে, কেবলমাত্র ট্যাবগুলির মাধ্যমে পুনর্নির্মাণের জন্য স্থানটি \ t দিয়ে প্রতিস্থাপন করুন এবং আপনি যদি আরও কলাম পেতে চান তবে উদাহরণ হিসাবে আপনি এটি করতে পারেনawk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
ফাতিহসারিগল

64

আপনি একত্রিত করতে পারেন cutএবং paste:

paste <(cut -f2 file.txt) <(cut -f1 file.txt)

মন্তব্যের মাধ্যমে: বাশিজম এড়ানো এবং কাটা কাটা একটি দৃষ্টান্তটি করা সম্ভব:

paste file.txt file.txt | cut -f2,3

3
এটি "চতুরতার সাথে" যোগ্যতা অর্জন করে কিনা তা নিশ্চিত নয়, তবে: f = file.txt পেস্ট <(কাট -f2 $ ফ) <(কাট -ফ 1 $ চ)। এছাড়াও, আমি নোট করি যে যখন আপনার প্রচুর কলাম থাকে এবং সেগুলির বৃহত ব্লকগুলির চারপাশে ঘুরতে চান তখন এই পদ্ধতিটি সবচেয়ে সহজ।
মাইকেল রাশ

একই কলামে চলক দৈর্ঘ্যের কক্ষগুলির সাথে কাজ করে না
ক্রাইমার

2
@ ক্রেমার আপনার মানে কি? cutভেরিয়েবল-দৈর্ঘ্যের কলামগুলির জন্য সূক্ষ্মভাবে কাজ করে যতক্ষণ আপনার অনন্য কলাম বিভাজক থাকে।
ট্রিপলি

1
অপ্রয়োজনীয় ফাইলটি অপসারণ করতে আপনি সম্ভবত টি ব্যবহার করতে পারেন:
JJW5432

2
এটা এড়ানোর করা সম্ভব bashisms এবং এক উদাহরণ হিসেবে বলা যায় অপসারণ cut: করে paste file.txt file.txt | cut -f2,3
AGC

7

শুধু খোল ব্যবহার করে,

while read -r col1 col2
do
  echo $col2 $col1
done <"file"

এটি প্রায়শই অদক্ষ। সাধারণত, আপনি দেখতে পাবেন যে সম্পর্কিত আওক স্ক্রিপ্টটি অনেক দ্রুত, উদাহরণস্বরূপ। আপনার মানগুলি উদ্ধৃত করার ক্ষেত্রেও যত্নবান হওয়া উচিত "$col2"এবং "$col1"- ডেটাতে শেল মেটাচার্যাক্টর বা অন্যান্য শেননিগান থাকতে পারে।
ট্রিপলি

7

আপনি তার জন্য পার্ল ব্যবহার করতে পারেন:

perl -ane 'print "$F[1] $F[0]\n"' < file.txt
  • -e বিকল্প মানে এর পরে কমান্ডটি কার্যকর করা
  • --n এর অর্থ রেখার দ্বারা লাইন পড়ুন (ফাইলটি খুলুন, এক্ষেত্রে STDOUT, এবং লাইনগুলি লুপ করুন)
  • -এর অর্থ @F ("F" - ক্ষেত্রের মত) নামক একটি ভেক্টরে এই জাতীয় লাইনগুলি বিভক্ত করুন। পার্ল ইনডেক্স ভেক্টরগুলি 0 থেকে শুরু করে কাটের বিপরীতে যা সূচী ক্ষেত্রগুলি ফর্ম 1 শুরু করে।
  • ডিফল্ট হোয়াইটস্পেসের পরিবর্তে ফাইলটি পড়ার সময় ফিল্ড বিভাজক হিসাবে প্যাটার্নটি ব্যবহার করতে আপনি -F প্যাটার্ন (-F এবং প্যাটার্নের মধ্যে কোনও স্থান নয় ) যুক্ত করতে পারেন

পার্ল চালানোর সুবিধাটি হ'ল (আপনি পার্লকে জানলে) কলামগুলি পুনরায় সাজানোর চেয়ে আপনি F এ আরও অনেক বেশি গণনা করতে পারেন।


পার্লরুন (1) দাবি করে - একটি অন্তর্নিহিতভাবে সেট করে -n তবে আমি যদি -n সেট ছাড়া চালাই তবে লুপ মনে হয় না। অস্বাভাবিক.
ট্রেনটন

কি সংস্করণ? আমার জন্য perl -ae printকাজ করেcat
pwes

5

ব্যবহার join:

join -t $'\t' -o 1.2,1.1 file.txt file.txt

মন্তব্য:

  • -t $'\t'ইন গনুহ join আরও বেশি ধারণাসম্পন্ন -t '\t' ছাড়া$ ব্যর্থ হয়, ( coreutils v8.28 এবং তার আগে?); এটি সম্ভবত একটি বাগ যা এর মতো পরিশ্রমী $হওয়া প্রয়োজন। দেখুন: ইউনিক্স বিভাজক চরটিতে যোগদান করুন

  • joinদুটি ফাইলের নাম প্রয়োজন, যদিও সেখানে কেবল একটি ফাইল কাজ করা হচ্ছে। joinকাঙ্ক্ষিত ক্রিয়া সম্পাদনের জন্য একই নামটি দু'বার কৌশল ব্যবহার করা।

  • স্বল্প সংস্থান সহ সিস্টেমগুলির জন্য joinঅন্যান্য উত্তরে ব্যবহৃত কয়েকটি সরঞ্জামের চেয়ে ছোট পদচিহ্ন সরবরাহ করে:

    wc -c $(realpath `which cut join sed awk perl`) | head -n -1
      43224 /usr/bin/cut
      47320 /usr/bin/join
     109840 /bin/sed
     658072 /usr/bin/gawk
    2093624 /usr/bin/perl

3

সবেমাত্র খুব অনুরূপ কিছু নিয়ে কাজ করছি, আমি কোনও বিশেষজ্ঞ নই তবে আমি ভেবেছিলাম যে আমি যে কমান্ডগুলি ব্যবহার করেছি সেগুলি ভাগ করব। আমার একাধিক কলাম সিএসভি ছিল যা আমাকে কেবল 4 টি কলামের প্রয়োজন এবং তারপরে সেগুলি পুনঃক্রম করতে আমার দরকার হয়েছিল।

আমার ফাইলটি পাইপ ছিল '|' সীমানা ছাড়াই তবে তা সরে যেতে পারে।

LC_ALL=C cut -d$'|' -f1,2,3,8,10 ./file/location.txt | sed -E "s/(.*)\|(.*)\|(.*)\|(.*)\|(.*)/\3\|\5\|\1\|\2\|\4/" > ./newcsv.csv

স্বীকারযোগ্যভাবে এটি সত্যিই রুক্ষ এবং প্রস্তুত তবে এটি অনুসারে টুইট করা যেতে পারে!


এটি উত্থাপিত প্রশ্নের উত্তর দেয় না। ওভারফ্লো স্ট্যাকের প্রবণতায় আপনার পোস্ট দেওয়ার আগে দয়া করে কোনও সমস্যার উত্তর দেওয়ার জন্য সময় দিন commit
বিল গালে

0

সেড ব্যবহার

কলাম কন্টেন্ট ক্যাপচার এবং পুনঃক্রম করতে মৌলিক নিয়মিত অভিব্যক্তির নেস্টেড subexpressions সঙ্গে সেড ব্যবহার করুন। এই ক্ষেত্রে যেমন কলামগুলি পুনরায় অর্ডার করতে সীমিত সংখ্যক কাটা রয়েছে তখন এই পদ্ধতির পক্ষে উপযুক্ত।

মৌলিক ধারণা সার্চ প্যাটার্ন পারিপার্শ্বিক আকর্ষণীয় অংশ হয় \(এবং \)সঙ্গে প্রতিস্থাপন প্যাটার্ন ফিরে প্লে করা যাবে না যা \#যেখানে# অনুসন্ধান প্যাটার্ন subexpression এর অনুক্রমিক অবস্থান প্রতিনিধিত্ব করে।

উদাহরণ স্বরূপ:

$ echo "foo bar" | sed "s/\(foo\) \(bar\)/\2 \1/"

উৎপাদনের:

bar foo

একটি subexpression বাইরের পাঠ্য স্ক্যান করা হয় কিন্তু প্রতিস্থাপন স্ট্রিং মধ্যে প্লেব্যাক জন্য ধরে রাখা হয় না।

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

ভাঙ্গন স্থানগুলি

সহজ ব্যবহারটি চিত্রিত করার জন্য, ধরে নিই যে একাধিক স্পেস একক স্পেসে বিভক্ত হতে পারে এবং দ্বিতীয় কলামের মানগুলি EOL (এবং স্থান প্যাডড নয়) দিয়ে সমাপ্ত হবে।

ফাইল:

bash-3.2$ cat f
Column1    Column2
str1       1
str2       2
str3       3
bash-3.2$ od -a f
0000000    C   o   l   u   m   n   1  sp  sp  sp  sp   C   o   l   u   m
0000020    n   2  nl   s   t   r   1  sp  sp  sp  sp  sp  sp  sp   1  nl
0000040    s   t   r   2  sp  sp  sp  sp  sp  sp  sp   2  nl   s   t   r
0000060    3  sp  sp  sp  sp  sp  sp  sp   3  nl 
0000072

ট্রান্সফর্ম:

bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f | od -a
0000000    C   o   l   u   m   n   2  sp   C   o   l   u   m   n   1  nl
0000020    1  sp   s   t   r   1  nl   2  sp   s   t   r   2  nl   3  sp
0000040    s   t   r   3  nl
0000045

কলাম প্রস্থ সংরক্ষণ করা

কলামগুলি পৃথক পৃথক প্রস্থের মঞ্জুরি দেওয়ার সময় ধীরে ধীরে প্রস্থের কলামগুলির সাথে ফাইলগুলিতে পদ্ধতিটি প্রসারিত করা যাক।

ফাইল:

bash-3.2$ cat f2
Column1    Column2
str1       1
str2       2
str3       3
bash-3.2$ od -a f2
0000000    C   o   l   u   m   n   1  sp  sp  sp  sp   C   o   l   u   m
0000020    n   2  nl   s   t   r   1  sp  sp  sp  sp  sp  sp  sp   1  sp
0000040   sp  sp  sp  sp  sp  nl   s   t   r   2  sp  sp  sp  sp  sp  sp
0000060   sp   2  sp  sp  sp  sp  sp  sp  nl   s   t   r   3  sp  sp  sp
0000100   sp  sp  sp  sp   3  sp  sp  sp  sp  sp  sp  nl
0000114

ট্রান্সফর্ম:

bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2
Column2 Column1
1       str1      
2       str2      
3       str3      
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2 | od -a
0000000    C   o   l   u   m   n   2  sp   C   o   l   u   m   n   1  sp
0000020   sp  sp  nl   1  sp  sp  sp  sp  sp  sp  sp   s   t   r   1  sp
0000040   sp  sp  sp  sp  sp  nl   2  sp  sp  sp  sp  sp  sp  sp   s   t
0000060    r   2  sp  sp  sp  sp  sp  sp  nl   3  sp  sp  sp  sp  sp  sp
0000100   sp   s   t   r   3  sp  sp  sp  sp  sp  sp  nl 
0000114

শেষ পর্যন্ত যদিও প্রশ্নের উদাহরণটিতে অসম দৈর্ঘ্যের স্ট্রিং নেই, তবে এই অভ্যাসটি এই ক্ষেত্রে সমর্থন করে।

ফাইল:

bash-3.2$ cat f3
Column1    Column2
str1       1      
string2    2      
str3       3      

ট্রান্সফর্ম:

bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3
Column2 Column1   
1       str1      
2       string2   
3       str3    
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3 | od -a
0000000    C   o   l   u   m   n   2  sp   C   o   l   u   m   n   1  sp
0000020   sp  sp  nl   1  sp  sp  sp  sp  sp  sp  sp   s   t   r   1  sp
0000040   sp  sp  sp  sp  sp  nl   2  sp  sp  sp  sp  sp  sp  sp   s   t
0000060    r   i   n   g   2  sp  sp  sp  nl   3  sp  sp  sp  sp  sp  sp
0000100   sp   s   t   r   3  sp  sp  sp  sp  sp  sp  nl 
0000114

শেলের অধীনে কলাম পুনঃক্রমের অন্যান্য পদ্ধতির সাথে তুলনা

  • আশ্চর্যজনকভাবে কোনও ফাইল ম্যানিপুলেশন সরঞ্জামের জন্য, জমিটি রেকর্ডের শেষ পর্যন্ত ক্ষেত্র থেকে কাটার জন্য অ্যাডক ভালভাবে উপযুক্ত নয়। Sed এই রেগুলার এক্সপ্রেশান্স ব্যবহার করে সম্পন্ন করা যেতে পারে, যেমন \(xxx.*$\)যেখানে xxxঅভিব্যক্তি কলাম মেলানো।

  • শেল স্ক্রিপ্টগুলির ভিতরে প্রয়োগ করার সময় পেস্ট এবং কাটা সাবশেলগুলি ব্যবহার করা জটিল হয়ে ওঠে। কমান্ডলাইন থেকে কাজ করা কোড শেল স্ক্রিপ্টের ভিতরে আনলে পার্স করতে ব্যর্থ হয়। কমপক্ষে এটি আমার অভিজ্ঞতা ছিল (যা আমাকে এই পদ্ধতির দিকে চালিত করেছিল)।


0

@ মেট থেকে উত্তরটি প্রসারিত করা, পার্ল ব্যবহার করে:
যদি ইনপুট এবং আউটপুটটি ট্যাব-বিস্মৃত হয়:

perl -F'\t' -lane 'print join "\t", @F[1, 0]' in_file

যদি ইনপুট এবং আউটপুট সাদা স্থান-সীমিত হয়:

perl -lane 'print join " ", @F[1, 0]' in_file

এখানে
-eপার্লকে আলাদা স্ক্রিপ্ট ফাইলের পরিবর্তে কোড ইনলাইনটি সন্ধান করতে বলেছে ,
-nএকবারে ইনপুট 1 লাইন পড়ে , লাইনটি পড়ার পরে
-lইনপুট রেকর্ড বিভাজক ( \n* NIX- এ) সরিয়ে দেয় chompএবং আউটপুট যুক্ত করে রেকর্ড বিভাজক ( \nপ্রতিটি * কিসসু দিকে) print,
-aঅ্যারের মধ্যে হোয়াইটস্পেস ইনপুট লাইন splits @F,
-F'\t'একযোগে সঙ্গে -aটুকরা ইনপুট ট্যাব এ অ্যারের মধ্যে হোয়াইটস্পেস লাইন, পরিবর্তে @F

@F[1, 0]@Fএই ক্রমে অ্যারের 2 ম এবং 1 ম উপাদানগুলির দ্বারা তৈরি অ্যারে হয় । মনে রাখবেন যে পার্লের অ্যারেগুলি শূন্য-সূচকযুক্ত, যখন ক্ষেত্রগুলি cut1-সূচিকৃত। সুতরাং ক্ষেত্রগুলি @F[0, 1]একই ক্ষেত্রগুলির মধ্যে রয়েছে cut -f1,2

নোট করুন যে এই জাতীয় স্বরলিপি উপরের পোস্ট হওয়া অন্যান্য উত্তরগুলির তুলনায় ইনপুটটির আরও নমনীয় ম্যানিপুলেশনকে সক্ষম করে (যা কোনও সাধারণ কাজের জন্য উপযুক্ত)। উদাহরণ স্বরূপ:

# reverses the order of fields:
perl -F'\t' -lane 'print join "\t", reverse @F' in_file

# prints last and first fields only:
perl -F'\t' -lane 'print join "\t", @F[-1, 0]' in_file
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.