আমি ধারাবাহিকভাবে উত্তর উদ্ধৃত দেখতে এই লিঙ্কে নিশ্চিতভাবেই জানায় "পার্স না ls
!" এটি বেশ কয়েকটি কারণে আমাকে বিরক্ত করে:
দেখে মনে হচ্ছে যে এই লিঙ্কটিতে থাকা তথ্যগুলি খুব কম প্রশ্ন সহ পাইকারিভাবে গ্রহণ করা হয়েছে, যদিও আমি নৈমিত্তিক পড়ার ক্ষেত্রে কমপক্ষে কয়েকটি ত্রুটি বাছাই করতে পারি।
এটিও মনে হয় যেন সেই লিঙ্কে বর্ণিত সমস্যাগুলি সমাধানের সন্ধান করার কোনও ইচ্ছা পোষণ করে না।
প্রথম অনুচ্ছেদ থেকে:
... আপনি যখন
[ls]
ফাইলগুলির তালিকার জন্য জিজ্ঞাসা করবেন তখন একটি বিশাল সমস্যা রয়েছে: ইউনিক্স কোনও সাদা নাম, নিউলাইনস, কমা, পাইপ প্রতীক এবং অন্য যে কোনও কিছুতে আপনি কখনও চেষ্টা করতে চাইলে ফাইলের প্রায় কোনও চরিত্রের অনুমতি দেন allows NUL ব্যতীত ডিলিমিটার ...ls
ফাইলের নামগুলি নতুন লাইনের সাথে পৃথক করে। আপনার কাছে নতুন নামে একটি ফাইল না হওয়া পর্যন্ত এটি ঠিক আছে। এবং যেহেতু আমি এর কোনও প্রয়োগের কথা জানি না তাইls
আপনাকে নিউলাইনের পরিবর্তে NUL টি অক্ষরের সাথে ফাইলের নাম শেষ করতে দেয়, এটি আমাদের নিরাপদে ফাইল নামগুলির একটি তালিকা পেতে অক্ষম করেls
।
বামার, তাই না? কিভাবে কি কখনো আমরা একটি newline ডেটা রয়েছে যা নতুন লাইন থাকতে পারে জন্য তালিকাভুক্ত ডেটা সেটটি সমাপ্ত সামলাতে পারবে? ঠিক আছে, যদি এই ওয়েবসাইটে প্রশ্নের উত্তর দেওয়া লোকেরা প্রতিদিন ভিত্তিতে এই ধরণের জিনিস না করে তবে আমি ভাবতে পারি যে আমরা কোনও সমস্যায় পড়েছি।
সত্য যদিও, বেশিরভাগ ls
বাস্তবায়নগুলি তাদের আউটপুট বিশ্লেষণের জন্য খুব সহজ এপিআই সরবরাহ করে এবং আমরা সকলেই এমনকি এটি উপলব্ধি না করেও এটি করে চলেছি। নাল দিয়ে আপনি কেবল একটি ফাইলের নামই শেষ করতে পারবেন না, আপনি নাল দিয়েও শুরু করতে পারেন বা অন্য কোনও স্বেচ্ছাসেবী স্ট্রিং যা আপনার ইচ্ছা হতে পারে। আরও কি, আপনি ফাইল-টাইপ অনুসারে এই স্বেচ্ছাচারী স্ট্রিংগুলি নির্ধারণ করতে পারেন । অনুগ্রহ করে বিবেচনা করুন:
LS_COLORS='lc=\0:rc=:ec=\0\0\0:fi=:di=:' ls -l --color=always | cat -A
total 4$
drwxr-xr-x 1 mikeserv mikeserv 0 Jul 10 01:05 ^@^@^@^@dir^@^@^@/$
-rw-r--r-- 1 mikeserv mikeserv 4 Jul 10 02:18 ^@file1^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file2^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 02:27 ^@new$
line$
file^@^@^@$
^@
দেখুন এই আরো অনেক কিছুর জন্য।
এখন এটি এই নিবন্ধটির পরবর্তী অংশ যা সত্যই আমাকে পেয়েছে:
$ ls -l
total 8
-rw-r----- 1 lhunath lhunath 19 Mar 27 10:47 a
-rw-r----- 1 lhunath lhunath 0 Mar 27 10:47 a?newline
-rw-r----- 1 lhunath lhunath 0 Mar 27 10:47 a space
সমস্যাটি হ'ল আউটপুট থেকে
ls
, আপনি বা কম্পিউটার উভয়ই বলতে পারবেন না যে এর কোন অংশগুলি ফাইলের নাম গঠন করে। এটি কি প্রতিটি শব্দ? না এটি প্রতিটি লাইন? না। এই প্রশ্নের সঠিক কোনও উত্তর নেই: আপনি বলতে পারবেন না।এছাড়াও খেয়াল করুন যে কীভাবে
ls
আপনার ফাইলের নাম ডেটা গার্বল করে (আমাদের ক্ষেত্রে এটি "ক" এবং "নিউলাইন"\n
শব্দের মাঝে চরিত্রটিকে একটি প্রশ্ন প্রশ্নে রূপান্তরিত করে ......
আপনি যদি কেবল বর্তমান ডিরেক্টরিটিতে থাকা সমস্ত ফাইলের পুনরাবৃত্তি করতে চান তবে একটি
for
লুপ এবং একটি গ্লোব ব্যবহার করুন:
for f in *; do
[[ -e $f ]] || continue
...
done
লেখক এটা কল ফাইলের নামের garbling যখন ls
শেল globs ধারণকারী ফাইলের নামের একটি তালিকা ফেরৎ এবং তারপর একটি শেল উল্লিখিত glob ব্যবহার করার পরামর্শ একটি ফাইল তালিকা উদ্ধার করুন!
নিম্নোক্ত বিবেচনা কর:
printf 'touch ./"%b"\n' "file\nname" "f i l e n a m e" |
. /dev/stdin
ls -1q
f i l e n a m e
file?name
IFS="
" ; printf "'%s'\n" $(ls -1q)
'f i l e n a m e'
'file
name'
পসিক্স সংজ্ঞা দেয় -1
এবং -q
ls
অপারেশনগুলি তাই:
-q
- মুদ্রণযোগ্য ফাইল নাম অক্ষরের প্রতিটি উদাহরণকে<tab>
প্রশ্ন-চিহ্ন ('?'
) অক্ষর হিসাবে লিখতে বাধ্য করুন । ফলাফল যদি ডিফল্টরূপে এই বিকল্পটি সরবরাহ করতে পারে যদি আউটপুট কোনও টার্মিনাল ডিভাইসে থাকে।
-1
- (সংখ্যার অঙ্কের এক।) আউটপুটকে প্রতি লাইনে একটি করে প্রবেশ করতে বাধ্য করুন।
- Globbing নিজস্ব সমস্যা ছাড়াই নয় ?
ম্যাচ কোনো চরিত্র তাই একাধিক ম্যাচিং ?
একটি তালিকা ফলাফল একই ফাইল একাধিক বার ম্যাচ হবে। এটি সহজেই পরিচালনা করা হয়।
যদিও এই জিনিসটি কীভাবে করা যায় তা মুল বিষয় নয় - এটি সর্বোপরি খুব বেশি কিছু নেয় না এবং নীচে প্রদর্শিত হয় - কেন আমি তা করতে আগ্রহী ছিলাম । আমি এটি বিবেচনা হিসাবে, এই প্রশ্নের সেরা উত্তর গৃহীত হয়েছে। আমি আপনাকে পরামর্শ দিচ্ছি যে লোকেরা যা করতে পারে না তার চেয়ে তারা কী করতে পারে সে সম্পর্কে আরও বেশি করে ফোকাস করার চেষ্টা করুন । আপনার মনে হয়, কমপক্ষে ভুল প্রমাণিত হওয়ার সম্ভাবনা আপনি অনেক কম।
তবে কেন চেষ্টাও করবেন? স্বীকার করা, আমার প্রাথমিক অনুপ্রেরণা ছিল যে অন্যরা আমাকে বলতে থাকে যে আমি পারছি না। আমি খুব ভাল জানি যে ls
আউটপুটটি যতটা নিয়মিত এবং অনুমানযোগ্য ততক্ষণ আপনি এটির ইচ্ছা করতে পারতেন যতক্ষণ আপনি কী সন্ধান করবেন তা জানেন। ভুল তথ্য আমাকে বেশিরভাগ কাজ করার চেয়ে বেশি বিরক্ত করে।
সত্য, যদিও, প্যাট্রিক এবং উম্পাস কি। উভয়ই উত্তর উল্লেখযোগ্য ব্যতিক্রম ( উক্ত উত্তরটির দুর্দান্ত হ্যান্ডেল সত্ত্বেও) , আমি এখানে উত্তরগুলির বেশিরভাগ তথ্যকে বেশিরভাগই সঠিক হিসাবে বিবেচনা করি - একটি শেল গ্লোব উভয়ই আরও সহজ পার্সিংয়ের চেয়ে বর্তমান ডিরেক্টরিটি অনুসন্ধান করার ক্ষেত্রে এটি আরও কার্যকর ls
। তারা আমার ব্যাপারে অন্তত যথেষ্ট কারণ পারেন ভুল তথ্য উপরে প্রবন্ধে উদ্ধৃত প্রচারের না এবং তারা গ্রহণযোগ্য আত্মপক্ষ সমর্থন করতে চলেছেন ন্যায্যতা নয়, তবে " পার্স কখনো ls
। "
দয়া করে মনে রাখবেন প্যাট্রিক উত্তর এর অসঙ্গত ফলাফল বেশিরভাগই ব্যবহার তাকে ফলে zsh
তারপর bash
। zsh
- ডিফল্টরূপে - শব্দ-বিভক্ত $(
কমান্ড )
পোর্টেবল পদ্ধতিতে ফলাফল প্রতিস্থাপন করে না । সুতরাং তিনি যখন জিজ্ঞাসা করলেন বাকী ফাইলগুলি কোথায় গেল? এই প্রশ্নের উত্তর হ'ল আপনার শেল সেগুলি খেয়েছে। এজন্য আপনাকে পোর্টেবল শেল কোড SH_WORD_SPLIT
ব্যবহার zsh
এবং ডিল করার সময় ভেরিয়েবল সেট করতে হবে । আমি তার উত্তরে এটি নোট করতে ব্যর্থতা ভয়াবহ বিভ্রান্তিকর হিসাবে বিবেচনা করি।
Wumpus এর উত্তর আমার জন্য গনা না - একটি তালিকা প্রেক্ষাপটে ?
চরিত্র হল একটি শেল উল্লিখিত glob। আর কীভাবে বলব জানি না।
একাধিক ফলাফলের মামলা পরিচালনা করতে আপনাকে গ্লোবটির লোভকে সীমাবদ্ধ করতে হবে। নিম্নলিখিতটি কেবলমাত্র ভয়াবহ ফাইল নামের একটি পরীক্ষার ভিত্তি তৈরি করবে এবং এটি আপনার জন্য প্রদর্শন করবে:
{ printf %b $(printf \\%04o `seq 0 127`) |
sed "/[^[-b]*/s///g
s/\(.\)\(.\)/touch '?\v\2' '\1\t\2' '\1\n\2'\n/g" |
. /dev/stdin
echo '`ls` ?QUOTED `-m` COMMA,SEP'
ls -qm
echo ; echo 'NOW LITERAL - COMMA,SEP'
ls -m | cat
( set -- * ; printf "\nFILE COUNT: %s\n" $# )
}
আউটপুট
`ls` ?QUOTED `-m` COMMA,SEP
??\, ??^, ??`, ??b, [?\, [?\, ]?^, ]?^, _?`, _?`, a?b, a?b
NOW LITERAL - COMMA,SEP
?
\, ?
^, ?
`, ?
b, [ \, [
\, ] ^, ]
^, _ `, _
`, a b, a
b
FILE COUNT: 12
এখন আমি হবে নিরাপদ প্রতিটি ভাষার প্রতিটি অক্ষরের একটি নয় /slash
, -dash
, :colon
, অথবা আলফা-সাংখ্যিক শেল উল্লিখিত glob তারপর চরিত্র sort -u
অনন্য ফলাফলের জন্য তালিকা। এটি নিরাপদ কারণ ls
ইতিমধ্যে আমাদের জন্য কোনও মুদ্রণযোগ্য অক্ষর সংরক্ষণ করেছে। ঘড়ি:
for f in $(
ls -1q |
sed 's|[^-:/[:alnum:]]|[!-\\:[:alnum:]]|g' |
sort -u | {
echo 'PRE-GLOB:' >&2
tee /dev/fd/2
printf '\nPOST-GLOB:\n' >&2
}
) ; do
printf "FILE #$((i=i+1)): '%s'\n" "$f"
done
আউটপুট:
PRE-GLOB:
[!-\:[:alnum:]][!-\:[:alnum:]][!-\:[:alnum:]]
[!-\:[:alnum:]][!-\:[:alnum:]]b
a[!-\:[:alnum:]]b
POST-GLOB:
FILE #1: '?
\'
FILE #2: '?
^'
FILE #3: '?
`'
FILE #4: '[ \'
FILE #5: '[
\'
FILE #6: '] ^'
FILE #7: ']
^'
FILE #8: '_ `'
FILE #9: '_
`'
FILE #10: '?
b'
FILE #11: 'a b'
FILE #12: 'a
b'
নীচে আমি আবার সমস্যার দিকে এগিয়ে যাই তবে আমি আলাদা পদ্ধতি ব্যবহার করি। মনে রাখবেন - \0
নাল ছাড়াও - /
ASCII চরিত্রটি একমাত্র নামের নামের মধ্যে নিষিদ্ধ। আমি এখানে গ্লোবগুলি একপাশে রেখেছি এবং এর পরিবর্তে POSIX নির্দিষ্ট -d
বিকল্প ls
এবং এর জন্য POSIX নির্দিষ্ট -exec $cmd {} +
কন্সট্রাক্ট সংযুক্ত করি find
। যেহেতু find
কেবলমাত্র প্রাকৃতিকভাবেই /
ক্রমানুসারে একটিকে নির্গত করবে , নীচে সহজেই প্রতিটি প্রবেশের জন্য সমস্ত দন্ত সংক্রান্ত তথ্য সহ একটি পুনরাবৃত্ত এবং নির্ভরযোগ্যভাবে বিস্মৃত ফাইললিস্ট সংগ্রহ করা হয়। আপনি এই জাতীয় কিছু দিয়ে কী করতে পারেন তা কল্পনা করুন:
#v#note: to do this fully portably substitute an actual newline \#v#
#v#for 'n' for the first sed invocation#v#
cd ..
find ././ -exec ls -1ldin {} + |
sed -e '\| *\./\./|{s||\n.///|;i///' -e \} |
sed 'N;s|\(\n\)///|///\1|;$s|$|///|;P;D'
###OUTPUT
152398 drwxr-xr-x 1 1000 1000 72 Jun 24 14:49
.///testls///
152399 -rw-r--r-- 1 1000 1000 0 Jun 24 14:49
.///testls/?
\///
152402 -rw-r--r-- 1 1000 1000 0 Jun 24 14:49
.///testls/?
^///
152405 -rw-r--r-- 1 1000 1000 0 Jun 24 14:49
.///testls/?
`///
...
ls -i
খুব কার্যকর হতে পারে - বিশেষত যখন ফলাফলের স্বতন্ত্রতা প্রশ্নে আসে।
ls -1iq |
sed '/ .*/s///;s/^/-inum /;$!s/$/ -o /' |
tr -d '\n' |
xargs find
এগুলি কেবলমাত্র সবচেয়ে পোর্টেবল উপায় যা আমি ভাবতে পারি। জিএনইউ দিয়ে ls
আপনি করতে পারেন:
ls --quoting-style=WORD
এবং শেষ, এখান থেকে অনেক বেশী সাদাসিধে পদ্ধতি পার্সিংls
যে আমি inode সংখ্যার প্রয়োজন যখন বেশ প্রায়ই ব্যবহার ঘটতে:
ls -1iq | grep -o '^ *[0-9]*'
এটি কেবল ইনড নম্বরগুলি দেয় - যা অন্য একটি কার্যকর পসিক্স নির্দিষ্ট বিকল্প।
stat
আমার উত্তরটি ব্যবহার করছিলাম কারণ এটি প্রতিটি ফাইলের উপস্থিতি যাচাই করে। sed
জিনিসটির সাথে নীচে আপনার বিট কাজ করে না।
ls
প্রথম স্থানটি বিশ্লেষণ না করার চেয়ে ভাল হতে পারে ? আপনি যা বর্ণনা করছেন তা খুব শক্ত। এগুলি সব বোঝার জন্য আমার এটি ডিকনস্ট্রাক্ট করতে হবে এবং আমি তুলনামূলকভাবে সক্ষম ব্যবহারকারী। আপনি সম্ভবত আপনার গড় জো এ জাতীয় কিছু মোকাবেলা করতে সক্ষম হতে পারবেন না।
ls
আউটপুট পার্সিংয়ের যে কারণে ভুল হয়েছে তার সবগুলিই মূল লিঙ্কটিতে ভালভাবে কভার করা হয়েছিল (এবং অন্যান্য জায়গাগুলিতে প্রচুর পরিমাণে)। এই প্রশ্নটি যদি ওপি বুঝতে সাহায্যের জন্য জিজ্ঞাসা করত তবে এই প্রশ্নটি যুক্তিসঙ্গত হত, তবে পরিবর্তে ওপি তার ভুল ব্যবহার ঠিক আছে তা প্রমাণ করার চেষ্টা করছে।
parsing ls is bad
। এরকম for something in $(command)
এবং সঠিক ফলাফল পেতে শব্দ-বিভাজন উপর নির্ভর বৃহৎ সংখ্যাগরিষ্ঠ জন্য খারাপ command's
যা সহজ আউটপুট হবে না।
time bash -c 'for i in {1..1000}; do ls -R &>/dev/null; done'
= 3.18s বনামtime bash -c 'for i in {1..1000}; do echo **/* >/dev/null; done'
= 1.28s