সারি এবং কলামগুলি ট্রান্সপোস করা হচ্ছে


18

নীচের মত লাইনগুলির সাথে আমার একটি ফাইল আছে।

title1:A1
title2:A2
title3:A3
title4:A4
title5:A5

title1:B1
title2:B2
title3:B3
title4:B4
title5:B5

title1:C1
title2:C2
title3:C3
title4:C4
title5:C5

title1:D1
title2:D2
title3:D3
title4:D4
title5:D5

আমি কীভাবে এটি অর্জন করতে পারি?

title1    title2     title3    title4
A1         A2         A3         A4
B1         B2         B3         B4
C1         C2         C3         C4
D1         D2         D3         D4


দয়া করে দয়া করে জঞ্জাল ব্যবহার করবেন না, আপনি পাশাপাশি পার্ল বা পাইথন বা একটি বাস্তব প্রোগ্রামিং ল্যাঙ্গুয়েজের সাথে একটি কাস্টম সলিউশন রোল করতে পারেন বা যা চান তা পেতে একাধিক পাস দিয়ে ট্র / কাট ব্যবহার করতে পারেন
রুডলফ ওলা

উত্তর:



9

কমান্ড লাইন থেকে কলামগুলি দিয়ে সারিগুলি স্থানান্তরিত করার জন্য একটি কাস্টম সমাধান রোলিংয়ের বাইরে কেবলমাত্র আমি দেখেছি যে এটি করতে পারে এটি একটি সরঞ্জামকে বিদ্রূপাত্মক বলা হয় transpose

স্থাপন

দুর্ভাগ্যক্রমে এটি কোনও রেপোতে নেই সুতরাং আপনাকে এটি ডাউনলোড করে সংকলন করতে হবে। এটি বেশ সহজবোধ্য যেহেতু এটির উপর নির্ভর করে কোনও অতিরিক্ত লাইব্রেরি নেই। এটি এর মতো সম্পাদন করা যেতে পারে:

$ gcc transpose.c -o transpose

ব্যবহার

এটি সহজেই টেক্সট ফাইলগুলি সহজেই পরিচালনা করতে পারে। উদাহরণ স্বরূপ:

$ cat simple.txt 
X column1 column2 column3
row1 0 1 2
row2 3 4 5
row3 6 7 8
row4 9 10 11

এই কমান্ডটি ব্যবহার করে স্থানান্তর করা যায়:

$ transpose -t --fsep " " simple.txt 
X row1 row2 row3 row4
column1 0 3 6 9
column2 1 4 7 10
column3 2 5 8 11

এই কমান্ডটি transposeস্থানান্তর ( -t) এবং ক্ষেত্র বিভাজকটি একটি স্পেস ( --fsep " ") ব্যবহার করতে হবে ।

আপনার উদাহরণ

আপনার নমুনা ডেটা যেহেতু কিছুটা জটিল আকারে রয়েছে এটি 2 পর্যায়ক্রমে মোকাবেলা করা দরকার। প্রথমে আমাদের এটিকে এমন বিন্যাসে অনুবাদ transposeকরতে হবে যা মোকাবেলা করতে পারে।

এই আদেশটি চালানো, ডেটা আরও অনুভূমিকভাবে বন্ধুত্বপূর্ণ বিন্যাসে রাখবে:

$ sed 's/:/ /; /^$/d' sample.txt \
    | sort | paste - - - - -
title1 A1   title1 B1   title1 C1   title1 D1   title2 A2
title2 B2   title2 C2   title2 D2   title3 A3   title3 B3
title3 C3   title3 D3   title4 A4   title4 B4   title4 C4
title4 D4   title5 A5   title5 B5   title5 C5   title5 D5

এখন আমাদের কেবল শিরোনাম 1, শিরোনাম 2 ইত্যাদির গৌণ সংঘটনগুলি সরিয়ে ফেলতে হবে .:

$ sed 's/:/ /; /^$/d' sample.txt \
    | sort | paste - - - - - | sed 's/\ttitle[0-9] / /g'
title1 A1 B1 C1 D1 A2
title2 B2 C2 D2 A3 B3
title3 C3 D3 A4 B4 C4
title4 D4 A5 B5 C5 D5

এটি এখন এমন ফর্ম্যাটে রয়েছে যা transposeমোকাবেলা করতে পারে। নিম্নলিখিত আদেশটি পুরো স্থানান্তর করবে:

$ sed 's/:/ /; /^$/d' sample.txt \
    | sort | paste - - - - - | sed 's/\ttitle[0-9] / /g' \
    | transpose -t --fsep " "
title1 title2 title3 title4
A1 B2 C3 D4
B1 C2 D3 A5
C1 D2 A4 B5
D1 A3 B4 C5
A2 B3 C4 D5

8

আপনি awkতখন ডেটা প্রক্রিয়া করতে pasteএবং columnএটি ফর্ম্যাট করতে পারেন।

এখানে আমি ধরে নিচ্ছি যে title1আপনার পোস্টে কেবলমাত্র একটি উদাহরণ, এবং সেই :ডেটাটিতে শিরোনাম + ডেটার মধ্যে বিভাজক হিসাবে থাকে না ।

nকতগুলি কলাম মুদ্রণ করতে হবে তা বোঝায় (ড্যাশগুলিতে মেলে উচিত paste)।

awk -F":" -v n=4 \
'BEGIN { x=1; c=0;} 
 ++c <= n && x == 1 {print $1; buf = buf $2 "\n";
     if(c == n) {x = 2; printf buf} next;}
 !/./{c=0;next}
 c <=n {printf "%s\n", $2}' datafile | \
 paste - - - - | \
 column -t -s "$(printf "\t")"

আপনি যদি এটি আরও নমনীয় এবং বজায় রাখা সহজ করতে চান তবে আপনি এটি স্ক্রিপ্ট হিসাবে লিখতে পারেন। এখানে বাশ র‍্যাপার ব্যবহার করে awkপাইপ দেওয়া একটি উদাহরণ column। আপনি আরও ডেটা চেক করতে পারেন যেমন যেমন সমস্ত সারি জুড়ে শিরোনামগুলি সঠিক কিনা তা নিশ্চিত করা ইত্যাদি etc.

সাধারণত হিসাবে ব্যবহৃত:

$ ./trans -f data -c 4
title one  title two  title three  title four
A1         A2         A3           A4
B1         B2         B3           B4
C1         C2         C3           C4
D1         D2         D3           D4

হেডার সবসময় খাটো পরে তথ্য আপনার কাছে হেডার প্রস্থ সংরক্ষণ, তারপর পারা হলে printfসঙ্গে %-*sএবং লাফালাফি columnসব একসাথে।

#!/bin/bash

trans()
{
    awk -F":" -v ncol="$1" '
    BEGIN {
        level = 1 # Run-level.
        col   = 1 # Current column.
        short = 0 # If requested to many columns.
    }
    # Save headers and data for row one.
    level == 1 {
        head[col] = $1
        data[col] = $2
        if (++col > ncol) { # We have number of requested columns.
            level = 2
        } else if ($0 == "") { # If request for more columns then available.
            level = 2
            ncol  = col - 2
            short = 1
        } else {
            next
        }
    }
    # Print headers and row one.
    level == 2 {
        for (i = 1; i <= ncol; ++i)
            printf("%s\t", head[i])
        print ""
        for (i = 1; i <= ncol; ++i)
            printf("%s\t", data[i])
        level = 3
        col = ncol + 1
        if (!short)
            next
    }
    # Empty line, new row.
    ! /./ { print ""; col = 1; next }
    # Next cell.
    col > ncol {next}
    {
        printf "%s%s", $2, (col <= ncol) ? "\t" : ""
        ++col
    }
    END {print ""}
    ' "$2"
}

declare -i ncol=4  # Columns defaults to four.
file=""            # Data file (or pipe).

while [[ -n "$1" ]]; do
    case "$1" in
    "-c") ncol="$2"; shift;;
    "-f") file="$2"; shift;;
    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]\n" \
        "$(basename $0)" >&2;
        exit;;
    esac
    shift
done

trans "$ncol" "$file" | column -t -s "$(printf "\t")"

1
চমৎকার উত্তর! @ জোয়েলডাভিস এবং আমি এটি হ্যাক করছি, তবে আপনার উত্তরটি দুর্দান্ত!
slm

7

আপনার যে ফর্ম্যাটটি চান সেটি ফাইলে দেওয়ার জন্য এখানে একটি দ্রুত উপায় রয়েছে:

$ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
A1  A2  A3  A4
B1  B2  B3  B4
C1  C2  C3  C4
D1  D2  D3  D4

আপনি যদি কলাম শিরোনাম চান:

$ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr '\n' '\t'; \
    echo ""; \
    grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
title1  title2  title3  title4  
A1      A2      A3      A4
B1      B2      B3      B4
C1      C2      C3      C4
D1      D2      D3      D4

২ য় কমান্ড কীভাবে কাজ করে

ব্যানার মুদ্রণ
grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr '\n' '\t';
ব্যানার পরে একটি রিটার্ন স্থাপন
echo
তথ্য সারি মুদ্রণ
grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -

পেস্ট কমান্ড সহজভাবে আমার কাজ সম্পন্ন। উত্তরের জন্য ধন্যবাদ ...
এস কে ভেঙ্কট


3

এটি গঠনের সম্ভবত আরও একটি সুসংগত উপায় আছে তবে এটি সাধারণ প্রভাবটি সম্পাদন করে বলে মনে হচ্ছে:

[jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr '\n' '\t' | sed 's/title1:/\n/g' ; echo

A1  A2  A3  A4  A5      
B1  B2  B3  B4  B5      
C1  C2  C3  C4  C5      
D1  D2  D3  D4  D5  
[jadavis84@localhost ~]$ 

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

একটি উত্তম উত্তর সম্ভবত সম্ভবত ব্যবহার sedবা awkএটি করতে এই প্রভাব নিচে ছড়িয়ে দেবে যাতে আপনার একবারে কেবল একটি জিনিস চলছে। তবে আমি ক্লান্ত তাই আমি একসাথে রাখতে সক্ষম হয়েছি।


জোয়েল - আমি একই ভুলটি করেছি এবং এটি কেবল লক্ষ্য করেছি, সে আউটপুটটিতে শিরোনাম 5 কলামটি চায় না।
slm

আহ, শেষ অবধি ভালভাবে চলমান এটি ঠিক করা উচিত। তবে দেখে মনে হচ্ছে সুক্মিন্ডারের সম্পূর্ণ সমাধান পোস্ট হয়েছে।
ব্র্যাচলে

1

pasteসম্ভবত আপনার সেরা বাজি। আপনার সাথে প্রাসঙ্গিক বিট নিষ্কাশন করতে পারেন cut, grepএবং awkএটি পছন্দ:

(awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)

যদি 5 তম কলামটি অপসারণ করা উচিত তবে এটি যুক্ত করুন awk 'NR%5':

(awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'

এখন এর সাথে কলামেট করুন paste:

(awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -

আউটপুট:

title1  title2  title3  title4
A1  A2  A3  A4
B1  B2  B3  B4
C1  C2  C3  C4
D1  D2  D3  D4

0

কেবল ট্রান্সপোজ অংশের জন্য, আমি সম্প্রতি একইরকম সমস্যা পেয়েছি এবং ব্যবহার করেছি:

awk -v fmt='\t%4s'  '{ for(i=1;i<=NF;i++){ a[i]=a[i] sprintf(fmt, $i); } } END { for (i in a) print a[i]; }'

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

নমুনা I / O:

i       mark    accep   igna    utaal   bta
-22     -10     -10     -20     -10     -10
-21     -10     -10     -20     -10     -10
-20     -10     -10     -20     -10     -10
-19     -10     0       -10     -10     -10
-18     0       0       -10     0       0
-12     0       0       -10     0       0
-11     0       0       -10     0       0
-10     0       0       -10     0       0

আউটপুট:

       i     -22     -21     -20     -19     -18     -12     -11     -10
    mark     -10     -10     -10     -10       0       0       0       0
    accep    -10     -10     -10       0       0       0       0       0
    igna     -20     -20     -20     -10     -10     -10     -10     -10
    utaal    -10     -10     -10     -10       0       0       0       0
     bta     -10     -10     -10     -10       0       0       0       0

-1

আপনি যা করতে পারেন তার মধ্যে সহজ কাজটি হল cutক্ষেত্রগুলি কাটা এবং তারপরে trআপনি যদি নতুন লাইনের অক্ষরটিকে একটি ট্যাব অক্ষরের সাথে প্রতিস্থাপন করে কলামগুলিতে সারিগুলি স্থানান্তর করছেন তবে ব্যবহার করুন : http://www.gnu.org/software/coreutils/manual/ coreutils.html # TR-আবাহন

cat file.txt | cut -d':' | tr '\n' '\t'

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