বিড়াল সঠিক ক্রমে একসাথে খুব বড় সংখ্যক ফাইল


23

আমার কাছে প্রায় ১৫,০০০ ফাইল রয়েছে যার নাম দেওয়া আছে file_1.pdb, file_2.pdbইত্যাদি doing আমি এগুলির মধ্যে কয়েক হাজার ক্রম করতে পারি:

cat file_{1..2000}.pdb >> file_all.pdb

তবে, আমি যদি 15,000 ফাইলের জন্য এটি করি তবে আমি ত্রুটি পেয়েছি

-bash: /bin/cat: Argument list too long

আমি দেখেছি এই সমস্যাটি সমাধান করে সমাধান করা হচ্ছে find . -name xx -exec xxতবে এটি যে ফাইলগুলির সাথে যুক্ত হয়েছে তা সংরক্ষণ করবে না n't আমি কীভাবে এটি অর্জন করতে পারি?


3
দশম ফাইলটির নাম কী? (বা একটি একক অঙ্ক সংখ্যা ক্রম বেশি যেকোনো ফাইল।)
roaima

আমার (এখন) একটি ডিরেক্টরিতে এই ফাইলগুলির 15,000 রয়েছে এবং আপনার cat file_{1..15000}.pdbনির্মাণ আমার পক্ষে ভাল কাজ করে।
রোয়াইমা

11
সীমাটি কি সিস্টেমের উপর নির্ভর করে। getconf ARG_MAXবলা উচিত।
ilkkachu

3
আপনার প্রশ্নটিকে "হাজার হাজার" বা "খুব সংখ্যক" ফাইলগুলিতে পরিবর্তন করার বিষয়টি বিবেচনা করুন। অনুরূপ সমস্যাযুক্ত অন্যান্য ব্যক্তির পক্ষে প্রশ্নটি সহজ করে তুলতে পারে।
মিসৌথ

উত্তর:


49

ব্যবহার find, sortএবং xargs:

find . -maxdepth 1 -type f -name 'file_*.pdb' -print0 |
sort -zV |
xargs -0 cat >all.pdb

findকমান্ড সমস্ত প্রাসঙ্গিক ফাইল খুঁজে বের করে, তারপর বাইরে তাদের pathnames ছাপে sortযে একটি "সংস্করণ সাজানোর" তাদেরকে সঠিক অনুক্রমে পেতে আছে (যদি ফাইলের নামের সংখ্যা ছিল একটি নির্দিষ্ট শূন্য ভরা প্রস্থ আমরা প্রয়োজন হতো না -V)। xargsবাছাই করা পথের নামের এই তালিকাটি নেয় এবং catএগুলি যতটা সম্ভব বড় ব্যাচে চালানো হয়।

ফাইলনেমগুলিতে নিউলাইন এবং স্পেসের মতো অদ্ভুত অক্ষর থাকলেও এটি কাজ করা উচিত। আমরা ব্যবহার -print0সঙ্গে findদিতে sortসাজানোর nul-সমাপ্ত নাম এবং sortহ্যান্ডলগুলি এই ব্যবহার -zxargsএছাড়াও এর -0পতাকা সহ নুল-সমাপ্ত নামগুলি পড়ে ।

নোট করুন যে আমি এমন কোনও ফাইলে ফলাফল লিখছি যার নামটির সাথে মেলে না file_*.pdb


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

অ-মানক পতাকা ব্যবহৃত হয়

  • -maxdepth 1, findকেবলমাত্র শীর্ষ-ডিরেক্টরিতে প্রবেশ করতে কিন্তু কোনও উপ-ডিরেক্টরিতে প্রবেশ করতে পারেন । পজিকলি, ব্যবহার করুনfind . ! -name . -prune ...
  • -print0, findআউটপুট নুল-টার্মিনেটেড পথের নামগুলি তৈরি করতে (এটি পসিক্স বিবেচনা করেছিল তবে প্রত্যাখ্যান করা হয়েছিল)। -exec printf '%s\0' {} +পরিবর্তে একটি ব্যবহার করতে পারে ।
  • -z, sortনাল-সমাপ্ত রেকর্ড নিতে। কোনও পসিক্স সমতুল্যতা নেই।
  • -V, sortসাজানোর যেমন উদাহরণ 200পরে 3। এখানে কোনও পসিক্স সমতুল্যতা নেই, তবে ফাইলনামগুলির একটি নির্দিষ্ট উপসর্গ থাকলে ফাইলের নির্দিষ্ট অংশগুলিতে একটি সংখ্যাসূচক সাজানো দ্বারা প্রতিস্থাপন করা যেতে পারে।
  • -0, xargsপড়া শূন্য রেকর্ড করতে। কোনও পসিক্স সমতুল্যতা নেই। POSIXly, এক স্বীকৃত ফর্ম্যাটে ফাইলের নাম উদ্ধৃত করা প্রয়োজন xargs

Pathnames ভাল ভদ্র হয়, আর যদি ডিরেক্টরি গঠন ফ্ল্যাট (কোন সাবডিরেক্টরি) হল, তারপর এক ছাড়া এই পতাকার ছাড়া কি, বানাতে পারে -Vসঙ্গে sort


1
এর জন্য আপনার নন স্ট্যান্ডার্ড নাল টার্মিনেশন দরকার নেই। এই ফাইলের নামগুলি অত্যন্ত বিরক্তিকর এবং POSIX সরঞ্জামগুলি তখন পরিচালনা করার পক্ষে সম্পূর্ণ সক্ষম।
কেভিন

6
আপনি আরও বেশি সংক্ষিপ্তভাবে প্রশ্নকারীর স্পেসিফিকেশন printf ‘file_%d.pdb\0’ {1..15000} | xargs -0 catবা কেভিনের বক্তব্য সহ, লিখতে পারতেন echo file_{1..15000}.pdb | xargs catfindসমাধান যথেষ্ট আরো ওভারহেড যেহেতু এটি ঐ ফাইল ফাইল-সিস্টেমের অনুসন্ধান করতে করেছে, কিন্তু এটা আরো দরকারী যখন কিছু ফাইল উপস্থিত না পারে।
কোজিরো

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

1
@ ক্রাইলিস একটি পুনর্নির্দেশটি কখনই কোনও কমান্ডের যুক্তির অংশ হয় না এবং এটি পুনর্নির্দেশের xargsপরিবর্তে catহয় (প্রতিটি অনুরোধ স্ট্যান্ডার্ড আউটপুট catব্যবহার করবে xargs)। যদি আমরা বলে থাকি xargs -0 sh -c 'cat >all.pdb'তবে এটির >>পরিবর্তে এটি ব্যবহার করা বোধগম্য হত, যদি এটিই >আপনি ইঙ্গিত দিচ্ছেন।
কুসালানন্দ

1
দেখে মনে হচ্ছে sort -n -k1.6এটি কাজ করবে (মূল, file_nnnফাইলের নামগুলির sort -n -k1.5জন্য বা আন্ডারস্কোর ছাড়াই একটির জন্য)।
স্কট

14

সহ zsh(যে {1..15000}অপারেটরটি কোথা থেকে আসে):

autoload zargs # best in ~/.zshrc
zargs file_{1..15000}.pdb -- cat > file_all.pdb

অথবা file_<digits>.pdbসংখ্যার ক্রমে সমস্ত ফাইলের জন্য :

zargs file_<->.pdb(n) -- cat > file_all.pdb

(যেখানে <x-y>একটি গ্লোব অপারেটর যা দশমিক সংখ্যার সাথে x থেকে y এর সাথে মেলে no কোনও xনয় y, এটি কোনও দশমিক সংখ্যা extendedglob'' s ' [0-9]##বা kshglob' এর +([0-9])(এক বা একাধিক সংখ্যার সমান )।

এর সাথে ksh93, তার বিল্টিন catকমান্ডটি ব্যবহার করে (সুতরাং execve()কোনও প্রয়োগ কার্যকর না হওয়ায় সিস্টেম কলের সেই সীমা দ্বারা প্রভাবিত হবে না ):

command /opt/ast/bin/cat file_{1..15000}.pdb > file_all.pdb

সঙ্গে bash/ zsh/ ksh93(সমর্থন যা zshএর {x..y}এবং printfbuiltin):

printf '%s\n' file_{1..15000}.pdb | xargs cat > file_all.pdb

একটি GNU সিস্টেম বা সামঞ্জস্যপূর্ণ, আপনি এছাড়াও ব্যবহার করতে পারেন seq:

seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb

জন্য xargsভিত্তিক সমাধান, বিশেষ যত্ন ফাইলের নাম যে ঐ খালি, একক বা ডবল কোট বা ব্যাকস্ল্যাশ ধারণ গ্রহণ করা হবে।

পছন্দ করুন -It's a trickier filename - 12.pdb, ব্যবহার করুন:

seq -f "\"./-It's a trickier filename - %.17g.pdb\"" 15000 |
  xargs cat > file_all.pdb

seq -f | xarg cat > সবচেয়ে মার্জিত এবং কার্যকর সমাধান। (এই প্রোগ্রামটিতে)।
হাস্তুর

ট্র্যাকিয়ার ফাইল ফাইলটি চেক করুন ... হতে পারে '"./-It'\''s a trickier filename - %.17g.pdb"'?
হাস্তুর

@ হাস্তুর, উফ! হ্যাঁ, ধন্যবাদ, আমি এটি একটি বিকল্প উদ্ধৃতি বাক্য গঠনতে পরিবর্তন করেছি। আপনার পাশাপাশি কাজ করবে।
স্টাফেন চেজেলাস

11

লুপের জন্য একটি সম্ভব এবং খুব সহজ।

for i in file_{1..15000}.pdb; do cat $i >> file_all.pdb; done

খারাপ দিকটি হ'ল আপনি catঅনেক বার নরকে ডাকে । তবে যদি আপনি ঠিক কীভাবে findস্টাফটি করবেন এবং এটির অনুরোধ ওভারহেড আপনার পরিস্থিতিতে খুব খারাপ না হয় তবে এটি মনে রাখা উচিত।


আমি প্রায়শই echo $i;একটি "অগ্রগতি সূচক" হিসাবে লুপের শরীরে একটি যোগ করি
রোল্ফ

3
seq 1 15000 | awk '{print "file_"$0".dat"}' | xargs cat > file_all.pdb

1
awk এখানে SeQ এর কাজ করতে পারেন এবং SeQ awk কাজ করতে পারেন: seq -f file_%.10g.pdb 15000। নোট করুন যে seqএকটি মানক কমান্ড নয়।
স্টাফেন চেজেলাস

ধন্যবাদ স্টাফেন - আমি মনে করি seq -f এটি করার একটি দুর্দান্ত উপায়; মনে আছে।
ল্যারিসি

2

প্রতিজ্ঞা

সুনির্দিষ্ট নামের ফর্ম্যাট [ 1 , 2 ] সহ কেবল 15k ফাইলের জন্য আপনাকে সেই ত্রুটিটি কাটা উচিত নয় ।

আপনি যদি অন্য ডিরেক্টরি থেকে এই সম্প্রসারণটি চালাচ্ছেন এবং আপনাকে প্রতিটি ফাইলে পাথ যোগ করতে হয় তবে আপনার কমান্ডের আকার আরও বড় হবে এবং অবশ্যই এটি ঘটতে পারে।

সমাধান সেই ডিরেক্টরি থেকে কমান্ড চালায়।

(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )

সর্বোত্তম সমাধান যদি এর পরিবর্তে আমি খারাপ অনুমান করে থাকি এবং আপনি ফাইলটি যে ডিরেক্টরিতে চালনা করেন এটি থেকে চালনা করুন ...
আইএমএইচও সর্বোত্তম সমাধান স্টাফেন চ্যাজেলাসের :

seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb

প্রিন্টফ বা সিক সহ; প্রাক-ক্যাশেডের মধ্যে কেবলমাত্র তাদের সংখ্যা সহ 15k ফাইলগুলিতে পরীক্ষিত এটি আরও দ্রুততর (বর্তমানে এবং একই ডিরেক্টরিতে ফাইলগুলি যে অপারেটিং সিস্টেমের মধ্যে রয়েছে ওপি বাদে) is

আরও কিছু শব্দ

আপনার শেল কমান্ড লাইনগুলিকে আরও দীর্ঘতর করতে সক্ষম হওয়া উচিত।
আপনার কমান্ড লাইনটি 213914 অক্ষর দীর্ঘ এবং 15003 শব্দ রয়েছে
cat file_{1..15000}.pdb " > file_all.pdb" | wc

... এমনকি প্রতিটি শব্দের জন্য 8 বাইট যোগ করা 333 938 বাইট (0.3M) থেকে খুব কম নীচে 2097142 (2.1M) দ্বারা প্রতিবেদন করা ARG_MAXহয়েছে যার কার্নেলটি 3.13.0 বা কিছুটা ছোট 2088232 হিসাবে রিপোর্ট করা হয়েছে "আমরা সম্ভবত সর্বোচ্চ কমান্ডের দৈর্ঘ্য নির্ধারণ করতে পারি ব্যবহার " দ্বারাxargs --show-limits

এর আউটপুটটিতে এটি আপনার সিস্টেমে একবার দেখুন

getconf ARG_MAX
xargs --show-limits

অলসতা গাইডড সমাধান

এই জাতীয় ক্ষেত্রে আমি ব্লকগুলির সাথে কাজ করতে পছন্দ করি এমনকি কারণ সাধারণত একটি সময় দক্ষ সমাধান আসে।
যুক্তি (যদি থাকে তবে) আমি 1 ... 1000 1001..2000 ইত্যাদি ইত্যাদি লিখতে খুব অলসতা করছি ...
তাই আমি আমার কাছে এটির জন্য একটি স্ক্রিপ্ট চাই।
আমি আউটপুটটি যাচাই করার পরে কেবলমাত্র এটিই স্ক্রিপ্টে পুনর্নির্দেশ করব red

... তবে অলসতা একটি মনের অবস্থা
যেহেতু আমার অ্যালার্জি রয়েছে xargs(আমার সত্যিই xargsএখানে ব্যবহার করা উচিত ছিল ) এবং এটি কীভাবে ব্যবহার করতে হয় তা আমি চেক করতে চাই না, তাই আমি নীচের উদাহরণগুলির মতো চাকাটিকে পুনর্বিবেচনা করার জন্য যথাযথভাবে শেষ করি (tl; dr)।

নোট করুন যেহেতু ফাইলের নামগুলি নিয়ন্ত্রণ করা হয় (কোনও ফাঁকা জায়গা নয়, নতুন লাইনগুলি ...) আপনি নীচের স্ক্রিপ্টের মতো সহজেই যেতে পারেন can

TL; ড

সংস্করণ 1: alচ্ছিক পরামিতি হিসাবে 1 ম ফাইল নম্বর, শেষ, ব্লকের আকার, আউটপুট ফাইল হিসাবে পাস করুন

#!/bin/bash
StartN=${1:-1}          # First file number
EndN=${2:-15000}        # Last file number
BlockN=${3:-100}        # files in a Block 
OutFile=${4:-"all.pdb"} # Output file name

CurrentStart=$StartN 
for i in $(seq $StartN $BlockN $EndN)
do 
  CurrentEnd=$i ;  
    cat $(seq -f file_%.17g.pdb $CurrentStart $CurrentEnd)  >> $OutFile;
  CurrentStart=$(( CurrentEnd + 1 )) 
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] && 
    cat $(seq -f file_%.17g.pdb $CurrentStart $EndN)  >> $OutFile;

সংস্করণ 2

সম্প্রসারণের জন্য কল করা বাশ (আমার পরীক্ষাগুলিতে কিছুটা ধীর ~ 20%)।

#!/bin/bash
StartN=${1:-1}          # First file number
EndN=${2:-15000}        # Last file number
BlockN=${3:-100}        # files in a Block 
OutFile=${4:-"all.pdb"} # Output file name

CurrentStart=$StartN 
for i in $(seq $StartN $BlockN $EndN)
do 
  CurrentEnd=$i ;
    echo  cat file_{$CurrentStart..$CurrentEnd}.pdb | /bin/bash  >> $OutFile;
  CurrentStart=$(( CurrentEnd + 1 )) 
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] && 
    echo  cat file_{$CurrentStart..$EndN}.pdb | /bin/bash  >> $OutFile;

অবশ্যই আপনি এগিয়ে যেতে পারেন এবং seq [ 3 ] (কোর্টিল থেকে) সম্পূর্ণরূপে মুক্তি পেতে পারেন এবং ব্যাশের ভেরিয়েবলগুলির সাথে সরাসরি কাজ করতে পারেন, বা পাইথন ব্যবহার করতে পারেন বা এটি করার জন্য এসি প্রোগ্রাম সংকলন করতে পারেন [ 4 ] ...


নোট যে %gসংক্ষিপ্ত %.6g। উদাহরণস্বরূপ এটি 1,000,000কে 1e + 06 হিসাবে উপস্থাপন করবে।
স্টাফেন চেজেলাস

সত্যিই অলস মানুষ কাজ করছে কাজটি জন্য ডিজাইন করা সরঞ্জামগুলি ব্যবহার যে মত E2BIG সীমাবদ্ধতা xargszsh এর, zargsবা ksh93এর command -x
স্টাফেন চেজেলাস

seqএটি কোনও বাশ বিল্টিন নয়, এটি জিএনইউ কোর্টিলস থেকে প্রাপ্ত একটি আদেশ। seq -f %g 1000000 1000000এমনকি কোরিউটিলের সর্বশেষতম সংস্করণেও 1e + 06 আউটপুট দেয়।
স্টাফেন চেজেলাস

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

@ স্টাফেনচাজেলাস গোটচা, ডান ... স্থির। ধন্যবাদ। আমি কেবল ওপি দ্বারা প্রদত্ত 15 কে ফাইল দিয়ে পরীক্ষা করেছি, আমার খারাপ।
হাস্তুর

0

এটি করার আরেকটি উপায় হতে পারে

(cat file_{1..499}.pdb; cat file_{500..999}.pdb; cat file_{1000..1499}.pdb; cat file_{1500..2000}.pdb) >> file_all.pdb
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.