ফাইল নামগুলিতে স্পেস, হাইফেন এবং আন্ডারস্কোর মুছবেন?


10

ডিরেক্টরিতে বা নির্বাচিত ফাইলগুলির সমস্ত ফাইল থেকে স্পেস, হাইফেন এবং আন্ডারস্কোরগুলি মুছতে একটি ভাল আদেশ কী?

আমি ফাইলের নামগুলি স্লুগাইফাই করতে থুনার কাস্টম অ্যাকশন সহ নিম্নলিখিত কমান্ডটি ব্যবহার করছি:

for file in %N; do mv "$file" "$(echo "$file" | tr -s ' ' | tr ' A-Z' '-a-z' | tr -s '-' | tr -c '[:alnum:][:cntrl:].' '-')"; done

তবে এই কমান্ডটি কেবল স্থানগুলি ড্যাশ / হাইফেন এবং ছোট হাতের অক্ষরযুক্ত অক্ষর দ্বারা প্রতিস্থাপন করে।

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

 rename "s/ //g" *

আবার এটি কেবল স্থানগুলি মুছে দেয় এবং হাইফেন / ড্যাশগুলি এবং আন্ডারস্কোরগুলিকেও নয়।

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


2
আমি একটি সমস্যা লক্ষ্য করেছি যে প্রচুর প্রস্তাবিত সমাধানগুলি ফাইলটি এমভি করার আগে "নতুন" নামটির উপস্থিতি সঠিকভাবে যাচাই করে নি। এটি না করা অনেক সমস্যার সম্ভাব্য উত্স হতে পারে।
এমডিপিসি

এটি পরীক্ষা করার জন্য জন1024 এর আদেশটি কি সংশোধন করা সম্ভব?
ব্যবহারকারী 8547

@ ব্যবহারকারী 8547rename -i "s/[-_ ]//g" *
স্পারহক

ধন্যবাদ স্পারাহক ঘটনাচক্রে, যারা এটি একটি থুনার কাস্টম অ্যাকশন হিসাবে ব্যবহার করতে আগ্রহী তাদের জন্য থুনার কমান্ডটি হ'ল% N তে ফাইলের জন্য; এমভি "$ ফাইল" করুন echo $file | sed -e 's/[ _-]//g'; সম্পন্ন
ব্যবহারকারী 8547

উত্তর:


11

প্যাকেজের renameসাথে এর সংস্করণটি perlনিয়মিত এক্সপ্রেশন সমর্থন করে:

rename "s/[-_ ]//g" *

অন্যথা,

rename -i "s/[-_ ]//g" *

-iপতাকা করতে সক্ষম হবে renameচুপটি মুছে যাওয়ার পরিবর্তে, ইন্টারেক্টিভ মোডে ব্যবহার করেন, প্ররোচনা যদি লক্ষ্য আগে থেকেই আছে।

পার্লের নাম পরিবর্তন কখনও কখনও বলা হয় prename

পার্লের নামকরণ বনাম ইউজার-লিনাক্সের নতুন নাম name

ডেবিয়ান-মতো সিস্টেমে পার্লের নাম পরিবর্তনটি ডিফল্ট বলে মনে হয় এবং উপরের কমান্ডগুলি কেবলমাত্র কাজ করা উচিত।

কিছু বিতরণে, renameইউজ-লিনাক্স থেকে ইউটিলিটিটি ডিফল্ট। এই ইউটিলিটি পার্লের সাথে সম্পূর্ণ বেমানান rename

  • সমস্ত: প্রথমে, পার্লের renameনামের অধীনে উপলব্ধ কিনা তা পরীক্ষা করে দেখুন prename

  • দেবিয়ান: পার্লের নাম পরিবর্তন হওয়া উচিত। এটি হিসাবে উপলব্ধ prenamerenameএক্সিকিউটেবল, যদিও, এর নিয়ন্ত্রণে /etc/alternativesএবং এইভাবে ভিন্ন কিছু রদবদল করা হয়ে থাকতে পারে।

  • আর্চলিনাক্স: চালান pacman -S perl-renameএবং কমান্ডটি হিসাবে উপলব্ধ perl-rename। আরও সুবিধাজনক নামের জন্য একটি উপনাম তৈরি করুন। (টুপি টিপ: ChiseledAbs)

  • ম্যাক ওএসএক্স মতে এই উত্তর , renamehomebrew মাধ্যমে ব্যবহার ওএসএক্স ইনস্টল করা যাবে:

    brew install rename 
  • সরাসরি ডাউনলোড: rename পার্ল সন্ন্যাসীদের থেকেও পাওয়া যায়:

     wget 'http://www.perlmonks.org/?displaytype=displaycode;node_id=303814' -O rename

আমি মনে করি এটি renameআপনি কী সম্পর্কে কথা বলছেন তার উপর নির্ভর করে । থেকে এক util-লিনাক্স -2.24.2-1.fc20.x86_64 রেগুলার এক্সপ্রেশনের সমর্থন করে না।
ক্রিশ্চিয়ান সিউপিতু

1
@ ক্রিশ্চিয়ানসিপিতু আপনার সন্ধানের পুনরায় নামকরণের সংস্করণটির জন্য আমি ম্যান পৃষ্ঠাটি পরীক্ষা করেছি। যুক্তিগুলির ভিত্তিতে, renameওপি যে সংস্করণটি ব্যবহার করছিল সেটি perlসংস্করণের মতো নয় সংস্করণটির মতো দেখাচ্ছে util-linux
1024

রেকর্ডের renameজন্য, এটি ইউজন-লিনাক্স সংস্করণের ম্যান পৃষ্ঠা । যাইহোক, এই নোটের পাশাপাশি, গুরুত্বপূর্ণ বিষয়টি হ'ল ওপি তার উত্তর পেয়েছে (এবং আপনি আমার কাছ থেকে একটি আপত্তি :- ডি)।
ক্রিশ্চিয়ান সিউপিতু

@ ক্রিশ্চিয়ানসিয়ুপিটু এটি খুঁজে পাওয়ার জন্য ধন্যবাদ। আপনার কাছে একটি +1 নিয়ে ফিরে আসছি।
1024

1
@ জন 1024 আর্চলিনাক্স, তবে আমি খুঁজে পেয়েছি কীভাবে, ঠিক pacman -S perl-renameতখনই আমি অনুমান করি যে আপনি উপনামটি করতে পারেন।
ChiseledAbs


4

গণনা করা হচ্ছে না mv, এর জন্য আপনার আসলে কোনও বাইরের প্রক্রিয়া দরকার নেই - আপনি কেবল ধরণের পুফ করতে পারেন ।

ifsqz() ( LC_ALL=C sqz=$1
    isf() { [ -e "$1" ] || [ -L "$1" ] ; }  
    set -- * ; set -f
    for f do isf "$f" || break
    IFS=$sqz; set -- $f; IFS=
    isf "$*" || mv -- "$f" "$*"
    done
)

তবুও, এর অর্থ mvপ্রতি ফাইলের অনুরোধ, এবং সম্ভবত renameএটি আরও ভাল। যদিও শুধুমাত্র দেওয়া কাজ করা উচিত একটি POSIX mvমধ্যে $PATHএবং POSIX শেল।

সুতরাং, আমি এর জন্য এক ধরণের পাগল ডেমো নিয়ে এসেছি। পরীক্ষার সেটটি তৈরি করা হয়:

tee - - - - <<CGEN |\
dd cbs=90 conv=unblock |\
sed 'G;$!N'";s/^/touch -- '/;s/$/'/" |sh
$( #BEGIN CGEN
   LC_ALL=C
   i= n='"$((i=((i=i+1)==10||i==39||i==47)>0?(i+1):i))"'
   printf '%b -_   ---___'  $(
   IFS=0; eval \
       printf '"\\\\%04o\\\\%04o "' "$(
       printf "$n"' "$i" '%s $(
       printf %.252d
#END
))"))
CGEN

প্রথম স্থানে আমি প্রথমে স্বীকৃতি জানাব যে উপরের কমান্ডটি এমন ফলাফল তৈরি করে যা অন্যান্য উপায়ে আরও সহজেই পাওয়া যায়। তবে অন্যান্য উপায়গুলি সম্ভবত কীভাবে করা হবে $IFSএবং একটি সামান্য (অসুস্থ?) কল্পনাশক্তি প্রদর্শন করবে না।

সুতরাং প্রথম বিটটি মোটামুটি সোজা-এগিয়ে রয়েছে:

  • tee পাইপগুলি এর ইনপুটটির 5 অনুলিপিগুলি দেয় - হেরিডোকোমেন্ট বলে CGEN

  • dd ব্লক প্রতি 90 বাইট এবং নতুন পাইপগুলিতে এটির ইনপুট অবরোধ করে ...

  • sedসেই দুটি ব্লকের মধ্যে দুটি \nইভলাইন চরিত্রের সাথে 'যোগ দেয়, ফলাফলগুলি এককভাবে উদ্ধৃত করে এবং touch --পাইপ আউট করার আগে প্রতিটি লাইন চক্রের জন্য স্ট্রিংকে প্রস্তুত করে ...

  • sh যা শেল কমান্ড হিসাবে সমস্ত ইনপুট কার্যকর করে

#CGENবিট যদিও ... ওয়েল, সংক্ষেপে ...

  • নীচে printf252 0s মুদ্রণ

  • শেষের জন থেকে পরবর্তী 252 পায় ''নাল-স্ট্রিং আর্গুমেন্ট এবং প্রতিটি বিষয়বস্তু ছাপে জন্য $nস্ট্রিং দ্বারা অনুসরণ" $i "

  • evalprintfএটি 2 টি ব্যাকস্ল্যাশ টুকরো টুকরো টুকরো করে অষ্টাল নাম্বার হিসাবে ব্যাখ্যাটির ফলাফলগুলি মুদ্রণের আগে পরবর্তী যুক্তিগুলির ব্যাখ্যা করে

  • সর্বশেষে প্রতিটি জোড়ের জন্য printfস্ট্রিং অনুসরণ করে অষ্টাল 2 এর জন্য বাইট মানগুলি মুদ্রণ করে-_ ---___

  • $nএকটি সমীকরণের সূচনা করা হয়েছে $iযা 10, 39, বা 47 এর মান বাদ দিয়ে প্রতিটি মূল্যায়নের জন্য একের পর এক বৃদ্ধি পাবে - (যেগুলি \newline, 'একক-উক্তি এবং /যথাক্রমে ASCII দশমিকের মধ্যে স্ল্যাশ)

শেষ ফলাফলটি এমন এক ডিরেক্টরি যা আমার চরসেটে 1 থেকে 255 অবধি একক-উদ্ধৃতি (কেবলমাত্র আরও একটি sed s///বিবৃতি এড়াতে এড়িয়ে যায় ) এবং /স্ল্যাশ বাদে প্রচুর কুৎসিত ফাইল নাম ধারণ করে । এই ফাইলের নামগুলি দেখতে এইরকম:

(set -- *; printf '%s\n\n##############\n\n%s\n' "${9}" "${34}")  | cat -A

   ---___ww -_   ---___xx -_   ---___yy -_   ---___zz -_   ---___{{ -_   ---___|| -_   ---$
$
___}} -_   ---___~~ -_   ---___^?^? -_   ---___M-^@M-^@ -_   ---___M-^AM-^A -_   ---___M-^BM-^B -_   ---___M-^CM-^C$
$
##############$
$
 -_   ---___M-ZM-Z -_   ---___M-[M-[ -_   ---___M-\M-\ -_   ---___M-]M-] -_   ---___M-^M-^ -_   ---___M-_M-_ -_$
$
---___M-`M-` -_   ---___M-aM-a -_   ---___M-bM-b -_   ---___M-cM-c -_   ---___M-dM-d -_   ---___M-eM-e -_   ---___$

এখন আমি এই ফাইলগুলিতে কিছু তথ্য পাব:

chksqz() ( LC_ALL=C sqz=$1
    set -- * ; set -f ; IFS= ; tc="$*"
    printf '#%s\n' \
        "There are $# files in this test directory." \
        "All filenames combined contain a total of ${#tc} bytes."
    IFS=$sqz ; set -- $* ; IFS= ; sc="$*"  
    printf "%s '$sqz'" \
        "#Of which ${#sc} bytes are not"\
        " and $((${#tc}-${#sc})) bytes are"
    set +f ; unset IFS
    printf ".\n#%s\n#Total:\t%d\n#Other:\t%d\n#'$sqz':\t%d\n" \
        "And to confirm these figures:" \
        $(  printf %s * | wc -c 
            printf %s * | tr -d "$sqz" | wc -c
            printf %s * | tr -dc "$sqz" | wc -c
))
chksqz '_ -'

আউটপুট

#There are 101 files in this test directory.
#All filenames combined contain a total of 17744 bytes.
#Of which 2692 bytes are not '_ -' and 15052 bytes are '_ -'.
#And to confirm these figures:
#Total: 17744
#Other: 2692
#'_ -': 15052

ঠিক আছে. এখন অবশেষে, কাজ করতে:

ifsqz '_ -'
chksqz '_ -'

আউটপুট

#There are 101 files in this test directory.
#All filenames combined contain a total of 2692 bytes.
#Of which 2692 bytes are not '_ -' and 0 bytes are '_ -'.
#And to confirm these figures:
#Total: 2692
#Other: 2692
#'_ -': 0

সফল! আপনি নিজের জন্য দেখতে পারেন:

ls

????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
???????????????????????????
???????????????????????????
???????????????????????????
????????????????????????????
????????????????????????????
????????????????
??????????????????????
????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
???????????????????????????
???????????????????????????
???????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
??????????????????????????
????????????????????????
????????????????????
??????????????????
????????????????????????????
??
????????????????????????????
??????????????????????????
????????????????????????????
????????????????????????????
????????????????????!!""##
??????????????????!!""##$$
????????????????!!""##$$%%
????????????!!""##$$%%&&((
????????!!""??##$$%%&&(())
$$%%&&(())**??++,,..0011
%%&&(())**++??,,..00112233
&&(())**++,,??..0011223344
))**++,,..??0011223344556
**++,,..00??11223344556677
22334455667788??99::;;<<==>>
445566778899??::;;<<==>>??@@
5566778899::;;??<<==>>??@@AA
6778899::;;<<??==>>??@@AABB
8899::;;<<==??>>??@@AABBCCDD
\\]]^^``aa??bbccddeeffgghh
]]^^``aabbc??cddeeffgghhii
^^``aabbccdd??eeffgghhiijj
??@@AABBCCDDEE??FFGGHHIIJJKK
AABBCCDDEEFF??GGHHIIJJKKLLM
BBCCDDEEFFGG??HHIIJJKKLLMMNN
CCDDEEFFGGHHII??JJKKLLMMNNOO
EEFFGGHHIIJJ??KKLLMMNNOOPPQQ
ffgghhiijjkk??llmmnnooppqqrr
gghhiijjkkllmm??nnooppqqrrss
iijjkkllmmnn??ooppqqrrsstt
jjkkllmmnnoo??ppqqrrssttuuvv
kkllmmnnooppqq??rrssttuuvvww
LLMMNNOOPPQQRR??SSTTUUVVWWXX
MNNOOPPQQRRSS??TTUUVVWWXXYY
OOPPQQRRSSTT??UUVVWWXXYYZZ[[
PPQQRRSSTTUUVV??WWXXYYZZ[[\\
RRSSTTUUVVWW??XXYYZZ[[\\]]
ssttuuvvwwxx??yyzz{{||}}~~??
ttuuvvwwxxyyz??z{{||}}~~????
uuvvwwxxyyzz{{??||}}~~??????
wwxxyyzz{{||??}}~~??????????
xxyyzz{{||}}~~??????????????
YYZZ[[\\]]^^??``aabbccddee
ZZ[[\\]]^^``??aabbccddeeff

2
+1 এর সৃজনশীল ব্যবহারের জন্য IFS+1printf
1024

@ জন 1024 - আসলেই মজাদার:set -- 'some arbitrary' args; eval printf '"%s\n"' "$(IFS=0; printf ' "$@" %s' $(printf %025d))"
মাইকজার্ভ

1
new="$(IFS=" -_"; printf %s $1)"একটি সাবশেল কাঁটাচামচ করে (ksh93 ব্যতীত) এবং নতুন নতুন লাইনের সাথে সমস্যা রয়েছে। অন্য বিকল্পটি হ'ল IFS=' -_'; set -- $1; IFS=; new="$*"(এবং আপনার লুপটি লুপের জন্য বদলে নেওয়া)
স্টাফেন চ্যাজেলাস

1
[ -e x ]xঅ-বিদ্যমান বা অ-অ্যাক্সেসযোগ্য ফাইলে একটি সিমলিংক হলে মিথ্যা ফিরিয়ে দেবে ।
স্টাফেন চেজেলাস

1
চমৎকার শেল কুং-ফু!
কাউন্টারমোড

2

আপনার যদি পার্ল থাকে তবে আপনার সাধারণত নামকরণ হয়। আপনি করতে পারেন:

> type rename
rename is /usr/bin/rename

এবং এই স্ক্রিপ্টটি কীভাবে লেখা আছে তা দেখান:

> cat /usr/bin/rename | head -n 5 #firt 5 lines for example
#!/usr/bin/perl -w
#
#  This script was developed by Robin Barker (Robin.Barker@npl.co.uk),
#  from Larry Wall's original script eg/rename from the perl source.
#

এই স্ক্রিপ্টটি -i পতাকা সমর্থন করে না (এটি আমার সিস্টেমে সংস্করণ), তবে সম্ভবত আপনার সমর্থন করে। যুক্তি সম্পর্কে কি। প্রথমটি হ'ল পিসিআরই ফর্ম্যাট সহ নিয়মিত এক্সপ্রেশন, এটি ফিল্টারের মতো কাজ করে, ইনপুট নামটিকে আউটপুট নামের পরিবর্তিত করে। অ্যাসিস্টিক '*' দ্বারা প্রদত্ত ইনপুট নামের তালিকা। উদাহরণস্বরূপ, আপনি:

> cd /tmp
> rename 's/ //g' *

প্রকৃতপক্ষে '*' এটিকে প্রসারিত করা যেতে পারে:

> rename 's/ //g' file1 file2 file3 othe files found in current directory

যখন আপনার কাছে সত্যিই বড় কাউন্ট ফাইল রয়েছে, আপনি ফাঁদে পড়বেন। শেল সিস্টেমটি গ্রহণের চেয়ে আপনার লাইনটি দীর্ঘায়িত করবে। তারপরে আপনি সন্ধান বা xargs ব্যবহার করে কাজ করতে পারবেন। 'ফাইন্ড' ব্যবহার করা সমস্যা, কারণ পুনর্নবীকরণকে ডিরেক্টরিতে থাকা ফাইল গণনার তুলনায় অনেকবার ডাকা হবে। -r বিকল্পের সাথে আরও ভাল ব্যবহার করুন এক নাম পরিবর্তন কল অনেকগুলি ফাইল পরিবর্তন করে। উদাহরণ স্বরূপ:

> ls | xargs -r rename 's/ //g'   #thats all, names will be appended at the end of this command.

শেষ সমস্যা, এর অর্থ কী:

's/ //g'

পরিবর্তিত নামগুলির জন্য এটি নিয়মিত প্রকাশ। প্রথম '/' এর পরে স্থান। এটি সনাক্ত করা হয়েছে এবং দ্বিতীয় '/' এর পরে স্ট্রিং দ্বারা প্রতিস্থাপিত হয়েছে। তবে খালি স্ট্রিংটি তৃতীয় '/' দিয়ে শেষ হয়েছে, তারপরে স্থানটি কিছুই দ্বারা প্রতিস্থাপন করা হবে। বিকল্প 'জি' এই অভিব্যক্তিটিকে পুনরাবৃত্তি করে তোলে। অভিব্যক্তি শুরু থেকে শেষ পর্যন্ত সমস্ত নামের জন্য হাঁটবে এবং সমস্ত স্থান সনাক্ত করে।

তবে আপনার যদি ট্যাব চরিত্র বা অন্য 'সাদা' চরিত্র থাকে? এই '' গুলি 'এর প্রতিস্থাপন রয়েছে। আর কোন অপ্রয়োজনীয় চরিত্র? কেবল এটি প্রকাশে যুক্ত করুন। বন্ধনী সহ সমস্ত বন্ধ, উদাহরণস্বরূপ:

's/[\s_-]//g'

এটাই সব. আপনি কি মিল দেখছেন? আমার মনে হয় আপনার ম্যান পার্লিক্রিক এবং ম্যান পার্ল্রেট পড়া উচিত, এটি আপনাকে ব্যাখ্যা করে (আমি আশা করি) নিয়মিত প্রকাশ কীভাবে কাজ করে। আপনার নিজের স্ক্রিপ্টে পুনর্নবীকরণ কমান্ডটি আপনার প্রয়োজন হলে ব্যবহার করতে পারেন।


1

নিম্নোক্ত shশেল লুপটি বর্তমান ডিরেক্টরিতে ফাইলের নাম থেকে সমস্ত স্পেস, আন্ডারস্কোর এবং ড্যাশগুলি সরিয়ে ফেলবে, বিদ্যমান ফাইলগুলি ওভাররাইট না করার জন্য যত্ন নিয়ে:

for f in *; do
    test -f "$f" || continue
    nf=$( echo "$f" | tr -d ' _-' )
    ! test -e "$nf" && echo mv "$f" "$nf"
done

জন্য bashএবং ksh, এবং যুক্তি দিয়ে কিছুটা আরও ভার্বোজ হচ্ছে:

for f in *; do
    if [[ -f "$f" ]]; then
        nf=$( tr -d ' _-' <<<"$f" )
        if [[ ! -e "$nf" ]]; then
            echo mv "$f" "$nf"
        fi
    fi
done

echoআপনি যখন নিশ্চিত হন তখন এটি সরিয়ে ফেলুন it

trকমান্ড (মুছে ফেলবে -dকোনো চরিত্র অক্ষরের দেওয়া সেটে) ( ' _-')। সেটটির একেবারে শুরু বা শেষের দিকে ড্যাশ থাকা গুরুত্বপূর্ণ, বা এটি অক্ষরের ব্যাপ্তি হিসাবে ব্যাখ্যা করা হবে।

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