ইউনিক্স সাজানোর ক্ষেত্রে শিরোনামের লাইনগুলিকে উপেক্ষা করার কোনও উপায় আছে কি?


102

আমার একটি স্থির-প্রস্থ-ফিল্ড ফাইল রয়েছে যা আমি ইউনিক্স (সাইগউইন, আমার ক্ষেত্রে) বাছাইয়ের ইউটিলিটি ব্যবহার করে বাছাই করার চেষ্টা করছি।

সমস্যাটি হ'ল ফাইলটির শীর্ষে একটি দুটি লাইন শিরোলেখ রয়েছে যা ফাইলের নীচে সাজানো হচ্ছে (প্রতিটি শিরোনাম লাইনটি একটি কোলন দিয়ে শুরু হয়)।

বাছাই করার কোনও উপায় আছে কিনা "প্রথমে দুইটি রেজিস্টার্ড অতিক্রম করুন" বা একটি ক্রম নির্দিষ্ট করুন যা কোলন লাইনগুলি শীর্ষে সাজিয়েছে - বাকি রেখাগুলি সর্বদা 6-সংখ্যার সংখ্যার সাথে শুরু করা হয় (যা আসলে আমি মূল কী) আমি বাছাই করছি) যদি এটি সাহায্য করে।

উদাহরণ:

:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00

বাছাই করা উচিত:

:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00

রেকর্ডের জন্য: আমি এখন অবধি যে কমান্ড লাইনটি ব্যবহার করছি তা হ'ল "বাছাই -t k -k1.1,1.6 <ফাইল>" [ডেটা ফাঁকা স্থান ধারণ করতে পারে তবে কখনও কোনও ব্যাকস্ল্যাশ থাকতে পারে না]
রব গিলিয়াম

উত্তর:


124
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile

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


ধন্যবাদ; আমি এই উত্তরটি সবচেয়ে সম্পূর্ণ এবং সংক্ষিপ্ত বলে মনে হচ্ছে বলে গ্রহণ করছি (এবং আমি বুঝতে পারি এটি কী করছে!) - এটি "মাথা -2 2" হওয়া উচিত, যদিও :-)
রব গিলিয়াম

1
ধন্যবাদ, 'মাথা' অংশটি স্থির করে দিন।
ববস

4
পাইপ-ইন ডেটাতে এই সংস্করণটি কাজ করার কোনও উপায় আছে কি? আমি চেষ্টা করেছিলাম tee >(head -n $header_size) | tail -n +$header_size | sort, তবে মাথাটি tail|sortপাইপের পরে চলবে বলে মনে হচ্ছে , তাই শিরোনামটি শেষ পর্যন্ত মুদ্রিত হবে। এই নির্জনবাদী বা একটি জাতি শর্ত?
ড্যামিয়েন পোলেট

আপনি সম্ভবত catস্ট্যান্ডিনকে কোনও অস্থায়ী ফাইলে পুনঃনির্দেশ করতে ব্যবহার করতে এমন কিছু টুকরো টুকরো টুকরো টুকরো করে ফেলতে পারেন , তারপরে সেই নতুন ফাইলে উপরের কমান্ডটি চালান, তবে এটি যথেষ্ট কুৎসিত হতে শুরু করেছে যে প্রদত্ত আঁক-ভিত্তিক সমাধানগুলির মধ্যে একটি ব্যবহার করা ভাল better অন্যান্য প্রতিক্রিয়া।
ববস

@DamienPollet: দেখুন ডেভ এর উত্তর
জোনাথন লেফলার

63

যদি আপনি ব্যবহার করতে আপত্তি না করেন তবে আপনি পাইপ ক্ষমতাগুলি অন্তর্নির্মিত awkকরতে পারেনawk

যেমন।

extract_data | awk 'NR<3{print $0;next}{print $0| "sort -r"}' 

এটি প্রথম দুটি লাইন ভারব্যাটিম মুদ্রণ করে এবং বাকী অংশগুলিকে পাইপ দেয় sort

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


2
খুব সুন্দর, এবং এটি কেবল ফাইল নয়, স্বেচ্ছাচারী পাইপগুলির সাথে কাজ করে!
lapo

4
সুন্দরী, জৌলুক কখনও আমাকে অবাক করে না। এছাড়াও, আপনার দরকার নেই $0, printযথেষ্ট।
nachocab

1
@ সামা ওয়াটকিন্স ফ্রিসেকের উত্তর কম কুৎসিত।
fess।

বাছাই করতে -r বিকল্পটি কী করছে? এটি কি বিপরীত সাজানোর কথা?
gvrocha 14'15

32

পাইপযুক্ত ডেটাতে কাজ করা একটি সংস্করণ এখানে:

(read -r; printf "%s\n" "$REPLY"; sort)

যদি আপনার শিরোনামে একাধিক লাইন থাকে:

(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)

এই সমাধানটি এখান থেকে


9
সুন্দর। একক শিরোলেখের ক্ষেত্রে আমি extract_data | (read h; echo "$h"; sort) এটি মনে রাখার জন্য যথেষ্ট সংক্ষিপ্ত ব্যবহার করি। আপনার উদাহরণ আরও প্রান্ত মামলা আবরণ। :) এটি সেরা উত্তর। পাইপ উপর কাজ করে। কোন অজানা।
fess।

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

নিস! আপনি যদি কেবল শিরোনাম খেতে চান তবে এটি মনে রাখা আরও সহজ:extract_data | (read; sort)
জেসন সুরেজ

এটি প্রায় নিখুঁত তবে আপনার নেতৃত্বাধীন এবং পিছনের স্থানগুলি রাখতে "পড়ুন" এর পরিবর্তে "আইএফএস = রিড" ব্যবহার করা উচিত।
স্টানিস্লাভ জার্মান-ইভতুশেনকো

6
এটি আমার মতে গ্রহণযোগ্য উত্তর হওয়া উচিত। সাধারণ, সংক্ষিপ্ত এবং আরও নমনীয় যে এটি পাইপযুক্ত ডেটাতেও কাজ করে।
পল আমি

12

সাধারণ ক্ষেত্রে, sedকাজটি মার্জিতভাবে করতে পারেন:

    your_script | (sed -u 1q; sort)

বা সমতুল্য,

    cat your_data | (sed -u 1q; sort)

কীটি হ'ল 1q- প্রথম লাইনে মুদ্রণ করুন (শিরোনাম) এবং প্রস্থান করুন (বাকি ইনপুটটি এতে রেখে sort)।

প্রদত্ত উদাহরণের জন্য, 2qকৌশলটি করবে।

-uসুইচ (unbuffered) তাদের জন্য প্রয়োজন বোধ করা হয় sedগুলি (উল্লেখ্য, গনুহ এর) অন্যথায়, খন্ডে ইনপুট পড়তে হবে যার ফলে ডাটা গ্রাসকারী যে আপনি মাধ্যমে যেতে চান sortপরিবর্তে।


1
হাই, @ আন্দ্রে; স্ট্যাক ওভারফ্লোতে স্বাগতম আমি ভয়েছি তোমার উত্তরটি কাজ করে না, আমি উইন্ডোজের গিত বাশে এটি পরীক্ষা করার সময় না (আমি সাইগউইন থেকে চলে এসেছি, আমি যে শেলটি আমি একটি আলাদা কাজটি ব্যবহার করেছিলাম years বছর আগে)। সেড কমান্ড স্ট্যান্ডিনের সমস্ত তথ্য টেনে নিয়ে যায়, কোনও তথ্যকে বাছাই করতে ছাড়েনি। কমান্ডটি আপনার_ডাটা বিড়াল করার চেষ্টা করুন (সেড 1 কিউ; ডাব্লুসি - এল) আমি কী বলতে চাইছি তা দেখতে।
রব গিলিয়াম

1
আপনি যদি দ্বিতীয় বার ইনপুটটি সেড কমান্ডের কাছে পাস করেন তবে এটি কাজ করতে পারে: বিড়াল সাজ্টমেক সিএসভি | (সেড 1 কি সার্টমেক.সিভিএস; সাজান-ট্ট,-কে 3-আরএন)> sort.csv
হ্যারি ক্র্যামার


4
head -2 <your_file> && nawk 'NR>2' <your_file> | sort

উদাহরণ:

> cat temp
10
8
1
2
3
4
5
> head -2 temp && nawk 'NR>2' temp | sort -r
10
8
5
4
3
2
1

3

এটিতে কেবল 2 লাইনের কোড লাগে ...

head -1 test.txt > a.tmp; 
tail -n+2 test.txt | sort -n >> a.tmp;

একটি সংখ্যার ডেটা জন্য, -n প্রয়োজন। আলফা সাজানোর জন্য, -n প্রয়োজন হয় না।

উদাহরণ ফাইল:
$ বিড়াল test.txt

শিরোনাম
8
5
100
1
-1

ফলাফল:
$ বিড়াল a.tmp

শিরোনাম
-1
1
5
8
100


1
এটি কি মূলত গৃহীত উত্তর হিসাবে একই উত্তর নয়? (ববসের পদ্ধতির ব্যতীত ফলাফল স্টডআউটে রাখে, আপনাকে প্রয়োজনে ফাইল লেখার আগে অন্যান্য ফিল্টারগুলির মাধ্যমে ফলাফল পাঠানোর অনুমতি দেয়)
রব গিলিয়াম

1

সুতরাং এখানে একটি বাশ ফাংশন যেখানে আর্গুমেন্টগুলি হুবহু সাজানোর মতো। সমর্থনকারী ফাইল এবং পাইপ।

function skip_header_sort() {
    if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
        local file=${@: -1}
        set -- "${@:1:$(($#-1))}"
    fi
    awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
}

কিভাবে এটা কাজ করে. এই লাইনটি অন্তত একটি যুক্তি আছে কিনা তা এবং চূড়ান্ত যুক্তি যদি কোনও ফাইল হয় তা পরীক্ষা করে।

    if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then

এটি ফাইলটিকে পৃথক যুক্তি হিসাবে সংরক্ষণ করে। যেহেতু আমরা শেষ যুক্তিটি মুছতে চলেছি।

        local file=${@: -1}

এখানে আমরা শেষ যুক্তিটি সরিয়েছি। যেহেতু আমরা এটিকে একটি বাছাই যুক্তি হিসাবে পাস করতে চাই না।

        set -- "${@:1:$(($#-1))}"

অবশেষে, আমরা awk অংশটি করি, আর্গুমেন্টগুলি পাস করে (মাইনাস শেষ আর্গুমেন্ট যদি এটি ফাইল হয়) এজেডকে সাজানোর জন্য। এটি ডেভ দ্বারা অরক্ষিতভাবে প্রস্তাবিত হয়েছিল, এবং সাজানোর যুক্তিগুলি সংশোধন করার জন্য সংশোধিত হয়েছিল। আমরা $fileপাইপ দিলে খালি হবে এই সত্যের উপর নির্ভর করি, এভাবে উপেক্ষা করা হবে।

    awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file

কমা দ্বারা পৃথক করা ফাইল সহ ব্যবহারের উদাহরণ।

$ cat /tmp/test
A,B,C
0,1,2
1,2,0
2,0,1

# SORT NUMERICALLY SECOND COLUMN
$ skip_header_sort -t, -nk2 /tmp/test
A,B,C
2,0,1
0,1,2
1,2,0

# SORT REVERSE NUMERICALLY THIRD COLUMN
$ cat /tmp/test | skip_header_sort -t, -nrk3
A,B,C
0,1,2
2,0,1
1,2,0

0

পাইথন সহ:

import sys
HEADER_ROWS=2

for _ in range(HEADER_ROWS):
    sys.stdout.write(next(sys.stdin))
for row in sorted(sys.stdin):
    sys.stdout.write(row)

প্রাক-ধারণা করুন সিস্টেমে পাইথন ইনস্টল করা আছে (খনিটি নেই)
রব গিলিয়াম

0

অন্যান্য উত্তর থেকে প্রাপ্ত একটি বাশ শেল ফাংশন এখানে। এটি ফাইল এবং পাইপ উভয়ই পরিচালনা করে। প্রথম যুক্তি হ'ল স্টিডিনের জন্য ফাইলের নাম বা '-'। বাকী যুক্তি সাজানোর জন্য পাস করা হয়। কয়েকটি উদাহরণ:

$ hsort myfile.txt
$ head -n 100 myfile.txt | hsort -
$ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r

শেল ফাংশন:

hsort ()
{
   if [ "$1" == "-h" ]; then
       echo "Sort a file or standard input, treating the first line as a header.";
       echo "The first argument is the file or '-' for standard input. Additional";
       echo "arguments to sort follow the first argument, including other files.";
       echo "File syntax : $ hsort file [sort-options] [file...]";
       echo "STDIN syntax: $ hsort - [sort-options] [file...]";
       return 0;
   elif [ -f "$1" ]; then
       local file=$1;
       shift;
       (head -n 1 $file && tail -n +2 $file | sort $*);
   elif [ "$1" == "-" ]; then
       shift;
       (read -r; printf "%s\n" "$REPLY"; sort $*);
   else
       >&2 echo "Error. File not found: $1";
       >&2 echo "Use either 'hsort <file> [sort-options]' or 'hsort - [sort-options]'";
       return 1 ;
   fi
}

0

এটি আয়ান শেরবিন উত্তরের মতো তবে আমার বাস্তবায়নটি হ'ল: -

cut -d'|' -f3,4,7 $arg1 | uniq > filetmp.tc
head -1 filetmp.tc > file.tc;
tail -n+2 filetmp.tc | sort -t"|" -k2,2 >> file.tc;

-4
cat file_name.txt | sed 1d | sort 

এটি আপনি যা চান তা করবে।


1) এটি কেবল শিরোনামের লাইনটি সরিয়ে দেয় এবং বাকীগুলি বাছাই করে, এটি শিরোনাম অক্ষত রেখে শিরোলেখ লাইনের নীচে সমস্ত কিছু সাজায় না। 2) এটি কেবল প্রথম লাইনটি সরিয়ে দেয়, যখন শিরোনামটি আসলে দুটি লাইন হয় (প্রশ্নটি পড়ুন)। 3) কেন আপনি "বিড়াল ফাইল_নাম.টেক্সট | সেড 1 ডি" ব্যবহার করেন যখন "সেড 1 ডি <ফাইল_নাম.টেক্সট" বা এমনকি "এসড 1 ডি ফাইল_নাম.টেক্সট" এর একই প্রভাব রয়েছে?
রব গিলিয়াম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.