কাস্টম ডিলিমিটার দিয়ে ফাইলের একাধিক লাইনের সাথে কীভাবে যুক্ত হবেন?


441

আমি ফলাফলকে ls -1এক লাইনে যোগ দিতে চাই এবং যা খুশি তা দিয়েই এটি সীমিত করে দিতে চাই।

এটি অর্জনের জন্য আমি ব্যবহার করতে পারি এমন কোনও স্ট্যান্ডার্ড লিনাক্স আদেশ রয়েছে?

উত্তর:


689

প্রথম বিকল্পটির মতোই তবে পেছনের ডিলিমিটার বাদ দেয়

ls -1 | paste -sd "," -

29
ঠিক একটি নোট হিসাবে, আমি চেষ্টা করেছি এমন পেস্টের সংস্করণটির শেষে এটি "ST" থেকে পড়তে বলার জন্য একটি যুক্তি প্রয়োজন। উদাহরণস্বরূপ ls -1 | paste -s -d ":" - নিশ্চিত নয় যে এটি পেস্টের সমস্ত সংস্করণ সহ সর্বজনীন কিনা
অ্যান্ডি হোয়াইট

4
এটি আরও ভাল কারণ এটি খালি ডিলিমিটারকে অনুমতি দেয় :)
ইউরা পূরবীভ

2
নোটটি ডিফল্ট হিসাবে (স্ট্যান্ডার্ড ইনপুট) pasteপায় -, অন্তত আমার উপর paste (GNU coreutils) 8.22
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

1
আমি কেবল এটি upvated, এটি এবং এখন এটি নির্বাচিত উত্তর মত একই ভোট আছে। এই উত্তর। কোনও পিছনে ডিলিমিটার নেই
thebugfinder

1
খালি ডিলিমিটার ব্যবহার করে নির্দিষ্ট করা যেতে পারে "\0", তাই paste -sd "\0" -আমার জন্য কাজ করেছে!
ব্র্যাড পার্কস

379

সম্পাদনা : সহজভাবে " ls -m " আপনি যদি চান আপনার ডিলিমেটারকে কমা হতে

আহ, শক্তি এবং সরলতা!

ls -1 | tr '\n' ','

কমা পরিবর্তন করুন " , " আপনি যা চান তেমন করুন। দ্রষ্টব্য যে এটিতে একটি "ট্রেলিং কমা" রয়েছে


46
+1, তবে আরও বিস্তৃত সংস্করণে শেষ \ n আলাদাভাবে পরিচালনা করা উচিত
মৌচিকেল

5
যদি ফাইলের নামের \nমধ্যে এটি থাকে তবে এটি এটিও প্রতিস্থাপন করবে।
কোডডিক্টেট

3
@ শ্রীভাত্সার: তার অর্থ একটি পেছনে সংযোজন নয় "," আমি বিশ্বাস করি। পছন্দls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
ক্রিস

7
@ ক্রিস: sedশেষ-চিহ্নিতকারী চরিত্রটির সাথে আপনার কিছুটা দক্ষ হতে পারে:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
পাইমান 72২

2
sedপরে trশেষ চিহ্নটি অপসারণ করার জন্য ব্যবহার করা অযৌক্তিক বলে মনে হয়। আমি সাথে যাইls -1 | tr '\n' ',' | head -c -1
reddot

29

এটি একটি নতুন লাইনের সাথে শেষ কমাটি প্রতিস্থাপন করে:

ls -1 | tr '\n' ',' | sed 's/,$/\n/'

ls -m স্ক্রিন-প্রস্থের অক্ষরে নতুন লাইনের অন্তর্ভুক্ত রয়েছে (উদাহরণস্বরূপ 80 তম)।

বেশিরভাগ বাশ (কেবলমাত্র lsবাহ্যিক):

saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS

বাশ 4 এ readarray(ওরফে mapfile) ব্যবহার করা :

readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS

পরামর্শের জন্য gniourf_gniourf ধন্যবাদ।


এটি নামের সাথে সাদা স্পেসযুক্ত ফাইলগুলির যত্ন নেবে না। এটি ব্যবহার করে দেখুন: dir = / tmp / testdir; rm -rf $ dir && mkdir $ dir && cd / ir dir && स्पर्श করুন "এটি একটি ফাইল" এটি_আইস_অ্যানডোর_ফায়াল && ls -1 && == ($ (ls -1)) এবং তালিকা = $ {ফাইলগুলি [@] /% / ,} && তালিকার = $ {তালিকা% *,} && প্রতিধ্বনি $ তালিকা
ডিমির

1
@ ডিমির: এই প্রশ্নের অনেক উত্তর এই সমস্যায় ভুগছে। আমি আমার উত্তরটি সম্পাদনা করেছি যাতে ট্যাব বা স্পেস সহ ফাইলের নামের অনুমতি দেওয়া হয়, তবে নতুন লাইনের নয়।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

আপনার বাশ সংস্করণটিও পথের নাম বিস্তারে ভুগছে। লাইন থেকে একটি অ্যারের নির্মাণ করতে, ব্যবহার করুন mapfileহিসাবে (ব্যাশ ≥4): mapfile -t files < <(ls -1)। সাথে ঝাঁকুনির দরকার নেই IFS। এবং এটি খুব ছোট।
gniourf_gniourf

এবং যদি আপনি আপনার অ্যারের আছে, আপনি ব্যবহার করতে পারেন IFSক্ষেত্র যোগদানের জন্য: saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS। অথবা আপনি যদি আরও একটি চরিত্রের সাথে আলাদা করতে চান তবে অন্য পদ্ধতিটি ব্যবহার করুন।
gniourf_gniourf

1
@gniourf_gniourf: আমি আপনার উত্তরগুলিতে আমার পরামর্শ অন্তর্ভুক্ত করেছি। ধন্যবাদ।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

24

আমি মনে করি এটি দুর্দান্ত

ls -1 | awk 'ORS=","'

ওআরএস হ'ল "আউটপুট রেকর্ড বিভাজক" তাই এখন আপনার লাইনগুলি কমা দিয়ে যুক্ত হবে।


6
এটি পেছনের সীমানা বাদ দেয় না।
ডেরেক মাহর

6
মাল্টি-ক্যারেক্টার রেকর্ড বিভাজক (যেমন, " OR ") পরিচালনা করার কারণে এটি বিশেষত দুর্দান্ত
ম্যাট শ্যাফার

15

সেটিং IFSএবং এর ব্যবহারের সংমিশ্রণটি "$*"আপনি যা করতে পারেন তা করতে পারে। আমি একটি সাবশেল ব্যবহার করছি তাই আমি এই শেলটির $ আইএফএসে হস্তক্ষেপ করব না

(set -- *; IFS=,; echo "$*")

আউটপুট ক্যাপচার করতে,

output=$(set -- *; IFS=,; echo "$*")

2
কীভাবে setকাজ করে সে সম্পর্কে আপনার কাছে আরও কিছু তথ্য আছে ? আমার কাছে কিছুটা ভুডোর মতো লাগছে। অগভীর চেহারা man setআমাকে খুব বেশি তথ্য নেট না।
এহতেশ চৌধুরী

3
আপনি যদি setএকগুচ্ছ যুক্তি দিয়ে থাকেন তবে কোনও বিকল্প নেই, তবে এটি অবস্থানগত পরামিতিগুলি সেট করে ($ 1, $ 2, ...)। প্রথম আর্গুমেন্ট (বা এই ক্ষেত্রে ফাইলের নাম) কোনও ড্যাশ দিয়ে শুরু হওয়ার ঘটনাটি --রক্ষা করার জন্য setরয়েছে। --বিকল্পের বিবরণটি দেখুন help set। আমি অবস্থানের পরামিতিগুলিকে জিনিসের একটি তালিকা পরিচালনা করার একটি সুবিধাজনক উপায় খুঁজে পাই। আমি output=$( files=(*); IFS=,; echo "${files[*]}" )
এটির

এটি দুর্দান্ত কারণ যেহেতু এটির জন্য কোনও অতিরিক্ত প্রোগ্রাম নির্বাহের প্রয়োজন হয় না এবং এটি ফাইলের নামের সাথে কাজ করে যা ফাঁকা স্থান এমনকি নিউলাইনও যুক্ত করে।
এরিক

1
@ এহতেশচৌধুরী যেমনটি type setআপনাকে বলবে set is a shell builtin,। সুতরাং, man setসাহায্য করবে না, তবে help setকরবে। উত্তর: "- অবস্থানগত পরামিতিগুলিতে কোনও অবশিষ্ট আর্গুমেন্ট বরাদ্দ করুন" "
স্টাফেন গৌরিচন

ক পরে set -- *। দেরি সম্প্রসারণ *এক স্তর আপনি একটি সাব শেলের প্রয়োজন ছাড়াই সঠিক আউটপুট পেতে পারেন: IFS=',' eval echo '"$*"'। অবশ্যই এটি অবস্থানগত পরামিতিগুলিকে পরিবর্তন করবে।
ইসহাক

13

lsসাধারণভাবে পার্সিংয়ের পরামর্শ দেওয়া হয় না , সুতরাং বিকল্পতর আরও ভাল উপায় ব্যবহার findকরা উদাহরণস্বরূপ:

find . -type f -print0 | tr '\0' ','

অথবা ব্যবহার করে findএবং paste:

find . -type f | paste -d, -s

একাধিক লাইনে যোগদানের জন্য (ফাইল সিস্টেমের সাথে সম্পর্কিত নয়), ইউনিক্স কমান্ড-লাইনে সংক্ষিপ্ত এবং বহনযোগ্য "যোগদান" পরীক্ষা করুন


9

চাকা পুনরুদ্ধার করবেন না।

ls -m

এটা ঠিক যে করে।


ওপি যে কোনও ডিলিমিটার চেয়েছিল তাই কমাতে রূপান্তর করতে আপনার এখনও ট্রির প্রয়োজন need এছাড়া কমা অর্থাত file1, file2 পর কোন space যোগ file3
ডাকাতি

তাই ব্যবহার ls -mএবং trকমা পরে জায়গা আপনাকে যা করতে হবে মুছে ফেলার জন্যls -m | tr -d ' '
অ্যান্ডি

2
টিআর এর ব্যবহার ফাইলের ভিতরে থাকা স্পেস মুছে ফেলবে। ব্যবহার করা আরও ভালsed 's/, /,/g
গ্লেন জ্যাকম্যান '

7

শুধু বাশ

mystring=$(printf "%s|" *)
echo ${mystring%|}


তবে লক্ষণীয়ভাবে |পিছনটি চম্প করে না , @ ক্যাম্।
ক্রিস্টোফার

1
ঠিক আছে, ন্যায়সঙ্গত bashএবং gnu printf
কোরিউটিলস

@ ক্যামহ তবে printf -vকেবল ব্যাশে কাজ করবে, যখন উপস্থাপিত উত্তরটি অনেকগুলি শেল প্রকারে কাজ করে।
ইসহাক

@Christopher হ্যাঁ, যে চিহ্ন মুছে ফেলা হবে |, এই শর্তে যে উভয় লাইন ব্যবহার করা হয়: printf -v mystring "%s|" * ; echo ${mystring%|}
ইসহাক

7

এই আদেশটি PERL অনুরাগীদের জন্য:

ls -1 | perl -l40pe0

এখানে 40 হ'ল স্থানের জন্য অষ্টাল আসকি কোড।

-p লাইন এবং মুদ্রণ দ্বারা লাইন প্রক্রিয়া করবে

-l আমরা প্রদান করা আসকি চরিত্রের সাথে the n পেছনের স্থানটি প্রতিস্থাপনের যত্ন নেবে।

- আমরা পিইআরএলকে অবহিত করব আমরা কমান্ড লাইন কার্যকর করছি।

0 এর অর্থ হ'ল বাস্তবায়নের কোন আদেশ নেই।

পার্ল -e0 পার্ল-ই 'এর সমান


6

ট্রির সম্ভাব্য নিউলাইন বিভ্রান্তি এড়াতে আমরা -b পতাকাটিকে ls তে যুক্ত করতে পারি:

ls -1b | tr '\n' ';'

5

দেখে মনে হচ্ছে উত্তরগুলি ইতিমধ্যে বিদ্যমান।

আপনি যদি a, b, cফর্ম্যাট করতে চান তবে ls -m( টিউলাইনস কর্ডোভার উত্তর) ব্যবহার করুন ) ব্যবহার করুন

অথবা আপনি যদি a b cফর্ম্যাট চান তবে ব্যবহার করুন ls | xargs( ক্রিস জেলের উত্তরের সরল সংস্করণ) )

বা আপনি যদি অন্য কোনও ডিলিমিটার চান তবে |ব্যবহার করুন ls | paste -sd'|'( আর্টেমের উত্তরের প্রয়োগ )


5

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

ls -1 | awk 'ORS=","' | head -c -1

আপনার ডিলিমিটার হিসাবে গণনা করা যতগুলি ট্রেলিং বাইট সরিয়ে ফেলুন।

আমি এই পদ্ধতির পছন্দ করি কারণ আমি বহু চরিত্রের ডেলিমিটারগুলি + এর অন্যান্য সুবিধাদি ব্যবহার করতে পারি awk:

ls -1 | awk 'ORS=", "' | head -c -2

সম্পাদনা

যেমনটি পিটার লক্ষ্য করেছেন, নেতিবাচক বাইট গণনাটি স্থানীয় ম্যাকোস সংস্করণে সমর্থিত নয় supported এটি তবে সহজেই ঠিক করা যায়।

প্রথমে ইনস্টল করুন coreutils। "জিএনইউ কোর ইউটিলিটি হ'ল জিএনইউ অপারেটিং সিস্টেমের বেসিক ফাইল, শেল এবং টেক্সট ম্যানিপুলেশন ইউটিলিটিস।"

brew install coreutils

MacOS দ্বারা প্রদত্ত কমান্ডগুলি "g" উপসর্গের সাথে ইনস্টল করা আছে। উদাহরণ স্বরূপgls

একবার এটি হয়ে গেলে আপনি ব্যবহার করতে পারেন gheadযার মধ্যে নেতিবাচক বাইট গণনা রয়েছে, বা আরও ভাল, উপনাম তৈরি করুন:

alias head="ghead"

দ্রষ্টব্য: নেতিবাচক বাইট গণনাগুলি কেবলমাত্র মাথার নির্দিষ্ট সংস্করণগুলিতে সমর্থিত, সুতরাং এটি ম্যাকোসগুলিতে কাজ করবে না।
পিটার

যে ইশারা জন্য ধন্যবাদ. আমি ম্যাকওএসের জন্য একটি সংযুক্তি যুক্ত করেছি।
আলেকসান্দার স্টেলম্যাকজোনেক

4

সরু পথ,

sed -e ':a; N; $!ba; s/\n/,/g'
  # :a         # label called 'a'
  # N          # append next line into Pattern Space (see info sed)
  # $!ba       # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop
  # s/\n/,/g   # any substitution you want

দ্রষ্টব্য :

এটি জটিলতায় লিনিয়ার, সমস্ত লাইন সেডের প্যাটার্ন স্পেসে যুক্ত হওয়ার পরে কেবলমাত্র প্রতিস্থাপিত হয়।

@ AnandRajaseka এর উত্তর , এবং যেমন কিছু অন্যান্য অনুরূপ উত্তর, এখানে হয় হে (ছিল n ²), কারণ sed প্রত্যেক বার এক একটা নতুন লাইন প্যাটার্ন স্পেস মধ্যে যোগ করা হয় প্রতিস্থাপন করতে হবে।

তুলনা করতে,

seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
  # linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
  # quadratic, hung

3

যদি আপনি xargs এর সংস্করণ -d পতাকা সমর্থন করে তবে এটি কাজ করা উচিত

ls  | xargs -d, -L 1 echo

-d হ'ল ডিলিমিটার পতাকা

আপনার যদি -d না থাকে তবে আপনি নিম্নলিখিতটি চেষ্টা করতে পারেন

ls | xargs -I {} echo {}, | xargs echo

প্রথম xargs আপনাকে আপনার ডিলিমিটার নির্দিষ্ট করতে দেয় যা এই উদাহরণে কমা।


3
-dজিএনইউ xargs সহ ইনপুট ডিলিমিটার নির্দিষ্ট করে, তাই কাজ করবে না। দ্বিতীয় উদাহরণটি এখানে শেষে একটি বিপথগামী ডিলিমিটারের অন্যান্য সমাধানগুলির মতো একই সমস্যাটি প্রদর্শন করে।
থোর

3
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

ব্যাখ্যা:

-e- কার্যকর করার জন্য একটি কমান্ড নির্দেশ করে
:a- এটি একটি লেবেল
/$/N- বর্তমান এবং (এন) এক্সট লাইনটির জন্য ম্যাচের
s/\n/\\n/;ক্ষেত্রটি নির্ধারণ করে \n
ta;- ম্যাচটি সফল হলে সমস্ত ইওএলকে প্রতিস্থাপন করে - গোটো লেবেল একটি

আমার ব্লগ থেকে নেওয়া ।



2

lsযখন পাইপের সাথে সংযুক্ত থাকে তখন একটি কলাম আউটপুট উত্পন্ন করে, তাই এটি -1অনর্থক।

বিল্টিন joinফাংশনটি ব্যবহার করে এখানে আরও একটি পার্ল উত্তর দেওয়া হয়েছে যা কোনও পিছনের ডিলিমিটারটি ছাড়বে না:

ls | perl -F'\n' -0777 -anE 'say join ",", @F'

অস্পষ্ট -0777প্রোগ্রামটি চালানোর আগে পার্লকে সমস্ত ইনপুট পড়তে দেয়।

সিড বিকল্প যা একটি পিছনে সীমানা ছাড়বে না

ls | sed '$!s/$/,/' | tr -d '\n'

0

lsকমা এবং একটি স্থান -mদিয়ে আউটপুট সীমিত করার বিকল্প রয়েছে ", "

ls -m | tr -d ' ' | tr ',' ';'

trস্থান বা কমাটি মুছে ফেলতে এই ফলাফলটি পাইপ করা trআপনাকে ফলসীমাটি পরিবর্তিত করতে পুনরায় ফলাফলটি পাইপ করতে দেয় ।

আমার উদাহরণে আমি ডিলিমিটারটি ডিলিমিটারের ,সাথে প্রতিস্থাপন করি;

আপনি ;যে কোনও একটি চরিত্রের ডেলিমিটারটি পছন্দ করেন তার সাথে প্রতিস্থাপন করুন যেহেতু আপনি যে স্ট্রিংগুলিতে আর্গুমেন্ট হিসাবে পাস করেন সেটিতে কেবলমাত্র প্রথম অক্ষরের জন্য অ্যাকাউন্ট থাকে accounts


0

আপনি একক লাইনে একাধিক লাইন একীভূত করতে chomp ব্যবহার করতে পারেন:

perl -e 'while (<>) {if (/ \ $ /) omp chomp; } মুদ্রণ; bad 'Bad0> পরীক্ষা

স্টেটমেন্টে লাইন ব্রেক কন্ডিশন রেখে দিন.এটি বিশেষ অক্ষর বা যে কোনও ডিলিমিটার হতে পারে।


0

পিছনে স্ল্যাশ হ্যান্ডলিং সহ দ্রুত পার্ল সংস্করণ:

ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'

ব্যাখ্যা করতে:

  • পার্ল-ই: বৈশিষ্ট্যগুলি সমর্থন করে পার্ল চালাও (বলুন ...)
  • বলুন: ক্যারিয়ার রিটার্ন সহ মুদ্রণ করুন
  • ",", ARRAY_HERE: "," এর সাথে একটি অ্যারে যোগ দিন
  • মানচিত্র {chomp; $ _} ROWS: ক্যারিয়ার প্রত্যাবর্তন করে প্রতিটি লাইন থেকে সরান এবং ফলাফলটি ফেরত দিন
  • <>: স্টিডিন, প্রতিটি লাইন একটি ROW, মানচিত্রের সাথে মিলিত করে এটি প্রতিটি ROW এর একটি অ্যারে তৈরি করবে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.