কোনও ফাইলের মধ্যে থাকা পাথের তালিকাকে পার্স করতে বেস নাম ব্যবহার করুন


9

আমি ম্যাক ওএসএক্স চালাচ্ছি এবং একই নামের সাথে থাকা ফাইলগুলির সংখ্যা খুঁজতে কমান্ড লাইনটি ব্যবহার করার চেষ্টা করছি।

আমি নিম্নলিখিত কমান্ডটি ব্যবহার করার চেষ্টা করেছি:

find ~ -type f -name "*" -print | basename | sort | uniq -d > duplicate_files

এটি কাজ করে না! আমি যখন নিম্নলিখিতগুলি করি:

find ~ -type f -name "*" -print > duplicate_files

তারপরে ডুপ্লিকেট_ফাইলে আমার সমস্ত ফাইলের পাথ থাকে। সুতরাং আমি মনে করি যে সমস্যাটি রয়েছে basename- এটি স্ট্যান্ডার্ড ইনপুট গ্রহণ করে না। আমি তখন নিম্নলিখিতটি চেষ্টা করেছিলাম:

basename $(find ~ -type f -name "*" -print) > duplicate_files

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

উত্তর:


16

basename এটির কমান্ড লাইন আর্গুমেন্টে কাজ করে, এটি স্ট্যান্ডার্ড ইনপুট থেকে পড়ে না।

আপনাকে basenameইউটিলিটিটি কল করার দরকার নেই , এবং আপনি আরও ভাল না চান: এটি কেবল যা করা হবে তা শেষের আগে অংশটি ছিনিয়ে /নেওয়া হবে এবং প্রতিটি প্রবেশের জন্য একটি বাহ্যিক কমান্ড কল করা ধীর হবে, আপনি একটি পাঠ্য প্রক্রিয়াকরণ ব্যবহার করতে পারেন পরিবর্তে ইউটিলিটি।

find ~ -type f | sed 's!.*/!!' | sort | uniq -d

ফাইলগুলির অবস্থানের উপর নজর রাখতে এটি আরও কার্যকর হতে পারে। নাম অনুসারে বাছাই করা অনুলিপিগুলি সনাক্ত করা সহজ করে তোলে, তবে sortশেষ ক্ষেত্রটি ব্যবহার করার বিকল্প নেই। আপনি যা করতে পারেন তা হ'ল /শুরুতে সর্বনিম্ন ক্ষেত্রটি অনুলিপি করুন , তারপরে বাছাই করুন এবং তারপরে ডুপ্লিকেটগুলি বের করতে এবং উপস্থাপন করতে কিছুটা অ্যাডহক অ্যাজক প্রক্রিয়াজাতকরণ ব্যবহার করুন।

find ~ -type f |
sed 's!.*/\(.*\)!\1/&!' |   # copy the last field to the beginning
sort -t/ -k1,1 |
cut -d/ -f2- |   # remove the extra first field (could be combined with awk below)
awk -F / '{
    if ($NF == name) {
        if (previous != "") {print previous; previous = ""}
        print
    } else {
        previous = $0
        name = $NF
    }
'

(মনে রাখবেন যে আমি ধরে নিলাম যে আপনার ফাইলের নামের কোনওটিতেই নতুন লাইন অক্ষর নেই))


সুপার ধন্যবাদ। আমি হুবহু এটি করার চেষ্টা করছিলাম ... খুব দরকারী
জনবি

7

findশুধু ফাইলের নাম আউটপুট দেওয়ার জন্য বিল্টিন বৈশিষ্ট্যগুলি কেন ব্যবহার করবেন না :

find ~ -type f -printf '%f\n' | sort | uniq -c

(ধরে নিলেন জিএনইউ find) বা কমপক্ষে এরকম কিছু:

find ~ -exec basename {} \; | sort | uniq -c

basename পাইপের মাধ্যমে পড়া বা একাধিক ফাইল প্রক্রিয়া করতে পারে না।

পুনশ্চ. -name '*'আপনি যদি সমস্ত ফাইল তালিকাভুক্ত করতে চান তবে নির্দিষ্ট করার দরকার নেই । এটি একটি ডিফল্ট বিকল্প।


ধন্যবাদ - '-প্রিন্টফ' ওএস এক্স ইউনিক্সের জন্য কাজ করে না
জনবি

এবং আমি যখন দ্বিতীয় সংস্করণটি পাই তখন চেষ্টা করি basename: unknown primary or operator-name "*"
টিপটির

এটা অদ্ভুত. আমি -printfপজিক্স ম্যান পৃষ্ঠাতেও দেখতে পাচ্ছি । দ্বিতীয় উপায় সহ ত্রুটি সম্পর্কে, এটি আমার উত্তরতে টাইপ করার কারণ। সংশোধন করা হয়েছে। আপনি কি আরও একবার চেষ্টা করতে পারেন?
তাড়াতাড়ি

এছাড়াও -printfআমি পেতে -printf: unknown primary or operator। এছাড়াও আমি যখন সংক্ষিপ্ত রেফারেন্স বইটিতে ইউনিক্সটি পরীক্ষা করেছিলাম এটি একটি জিএনইউ / লিনাক্স বিকল্প হিসাবে তালিকাভুক্ত করে
জনবি

1
আসলে সেরা উত্সটি man findআপনার কনসোলে থাকবে :)
রাশ

4

এটি OSX এ আমার জন্য কাজ করে বলে মনে হচ্ছে:

find ~ -type f -exec basename -a {} + | sort | uniq -d

হ্যাঁ - এটি দুর্দান্ত ধন্যবাদ - আগ্রহের বাইরে +কমান্ডটিতে কী বোঝায়?
জনবি

2
এটি কি দরকারী এটি দয়া করে ভোটাভুটি বিবেচনা করুন।
সন্দেহভাজন

এটি হ'ল - আমি বিচুয়েজে ভোট দিতে পারি না আমার 15 খ্যাতি দরকার :-(
জনবি

@ স্টাফেনচাজেলাস: বিএসডি বেসনামের ম্যান পেজ অনুসারে , এক্সিকিউটেবল আর্গুমেন্ট হিসাবে একাধিক স্ট্রিং নিতে পারে। আমি ওএসএক্সে ডাবল চেক করেছি, এটি কাজ করে।
রাহমু

1
ঠিক আছে দুঃখিত, আমি সংশোধন করছি। আমি বিএসডি এক্সটেনশান সম্পর্কে অবগত ছিলাম না। তবে, ঠিক দুটি ফাইল থাকলে তা এখনও ব্যর্থ হয়। সেই ক্ষেত্রেও কভার করার জন্য আপনার -aবিকল্পটি যুক্ত করতে হবে।
স্টাফেন চেজেলাস


2

আপনি পছন্দসই আউটপুট পেতে এর xargsসাথে এটি ব্যবহার করতে পারেন basename:

find ~ -type f -name "*" -print | xargs -l basename | sort | uniq -d > duplicate_files

0

এটির সাম্প্রতিক সংস্করণটি bashসহযোগী অ্যারে পরিচালনা করে, নিম্নলিখিতটি এম্বেডড নিউলাইনগুলি সহ পাথের নামগুলি অতিরিক্তভাবে পরিচালনা করবে:

#!/bin/bash

topdir=$HOME

shopt -s globstar  # enable the ** glob

declare -A count

# count the number of times each filename (base name) occurs
for pathname in "$topdir"/**; do
    # skip names that are not regular files (or not symbolic links to such files)
    [ ! -f "$pathname" ] && continue

    # get the base name
    filename=${pathname##*/}

    # add one to this base name's count
    count[$filename]=$(( ${count[$filename]} + 1 ))
done

# go through the collected names and print any name that
# has a count greater than one
for filename in "${!count[@]}"; do
    if [ "${count[$filename]}" -gt 1 ]; then
        printf 'Duplicate filename: %s\n' "$filename"
    fi
done

এটি কোনও বাহ্যিক ইউটিলিটি ব্যবহার করে না।

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