Awk কমান্ডের সাথে সদৃশ aw PATH এন্ট্রিগুলি সরান


48

আমি বাশ শেল ফাংশনটি লেখার চেষ্টা করছি যা আমাকে আমার প্যাথ এনভায়রনমেন্ট ভেরিয়েবল থেকে ডিরেক্টরিগুলির অনুলিপি অনুলিপি সরাতে দেয়।

আমাকে বলা হয়েছিল যে কমান্ডটি ব্যবহার করে একটি লাইন কমান্ড দিয়ে এটি অর্জন করা সম্ভব awkতবে এটি কীভাবে করব তা আমি বুঝতে পারি না। কেউ জানেন কীভাবে?



উত্তর:


37

যদি আপনার কাছে ইতিমধ্যে ডুপ্লিকেট নেই PATHএবং আপনি কেবল ডিরেক্টরিগুলি যুক্ত করতে চান তবে সেগুলি ইতিমধ্যে সেখানে না থাকলে আপনি কেবল শেল দিয়ে এটি সহজেই করতে পারেন।

for x in /path/to/add …; do
  case ":$PATH:" in
    *":$x:"*) :;; # already there
    *) PATH="$x:$PATH";;
  esac
done

এবং এখানে একটি শেল স্নিপেট যা এর থেকে সদৃশগুলি সরিয়ে দেয় $PATH। এটি একের পর এক এন্ট্রিগুলির মধ্য দিয়ে যায় এবং যা এখনও দেখা যায়নি তাদের অনুলিপি করে।

if [ -n "$PATH" ]; then
  old_PATH=$PATH:; PATH=
  while [ -n "$old_PATH" ]; do
    x=${old_PATH%%:*}       # the first remaining entry
    case $PATH: in
      *:"$x":*) ;;          # already there
      *) PATH=$PATH:$x;;    # not there yet
    esac
    old_PATH=${old_PATH#*:}
  done
  PATH=${PATH#:}
  unset old_PATH x
fi

এটি আরও ভাল হবে, যদি $ PATH এ আইট্রেট আইট্রেগুলি বিপরীতভাবে হয়, কারণ পরবর্তীগুলি সাধারণত নতুনভাবে যুক্ত হয় এবং তাদের মান আপ টু ডেট থাকতে পারে।
এরিক ওয়াং

2
@ এরিক ওয়াং আমি আপনার যুক্তি বুঝতে পারি না। PATH উপাদানগুলি সামনে থেকে পিছনে পিছনে যায়, সুতরাং যখন সদৃশ থাকে, তখন দ্বিতীয় নকল কার্যকরভাবে উপেক্ষা করা হয়। পিছন থেকে সামনের দিকে আইট্রেট করা অর্ডার পরিবর্তন করবে।
গিলস 'অশুভ হওয়া বন্ধ করুন'

@ গিলস যখন আপনি পাথের মধ্যে নকল ভেরিয়েবল রেখেছেন সম্ভবত এটি এটিকে যুক্ত করা হবে: PATH=$PATH:x=bমূল প্যাথের এক্স এর মান একটি হতে পারে, সুতরাং যখন ক্রমে পুনরাবৃত্তি হয়, তখন নতুন মানটিকে অগ্রাহ্য করা হবে, কিন্তু যখন বিপরীত ক্রমে নতুন মান কার্যকর হবে।
এরিক ওয়াং

4
@ এরিকওয়াং সেক্ষেত্রে যুক্ত হওয়া মানটির কোনও প্রভাব নেই তাই এড়ানো উচিত। পিছনে গিয়ে, আপনি যুক্ত করা মানটি আগে আসছেন। এখনো যোগ করেনি মান সামনে যাওয়ার কথা ছিল, এটা হিসাবে যোগ করা যেত PATH=x:$PATH
গিলস

@ গিলস যখন আপনি কিছু যুক্ত করেন, তার অর্থ এটি এখনও নেই, বা আপনি পুরানো মানটি ওভাররাইড করতে চান, সুতরাং আপনাকে নতুন যুক্ত ভেরিয়েবলটি দৃশ্যমান করা দরকার। এবং কনভেনশন অনুসারে সাধারণত এটি এভাবে যুক্ত হয়: PATH=$PATH:...না PATH=...:$PATH। বিপরীত ক্রম পুনরাবৃত্তি এটি আরও সঠিক। যদিও আপনার উপায়টিও কাজ করবে তবে লোকেরা বিপরীত পথে যুক্ত হয়।
এরিক ওয়াং

23

এখানে একটি বোধগম্য ওলাইনার সমাধান যা সমস্ত সঠিক কাজ করে: ডুপ্লিকেটগুলি সরিয়ে দেয়, পাথের ক্রম সংরক্ষণ করে এবং শেষে কোনও কোলন যুক্ত করে না। সুতরাং এটি আপনাকে একটি অনুলিপি PATH দেওয়া উচিত যা আসলটির মতো ঠিক একই আচরণ দেয়:

PATH="$(perl -e 'print join(":", grep { not $seen{$_}++ } split(/:/, $ENV{PATH}))')"

এটি সহজেই কোলন ( split(/:/, $ENV{PATH})) এ বিভক্ত হয় , grep { not $seen{$_}++ }প্রথম সংঘটন ব্যতীত কোনও পুনরাবৃত্ত পথগুলিকে ফিল্টার করার জন্য ব্যবহারগুলি ব্যবহার করে এবং তারপরে কোলন দ্বারা পৃথক করে পৃথক হয়ে যোগদান করে এবং ফলাফল মুদ্রণ করে ( print join(":", ...))।

আপনি যদি এর চারপাশে আরও কিছু কাঠামো চান, পাশাপাশি অন্যান্য ভেরিয়েবলগুলিও নকল করার ক্ষমতা চান তবে এই স্নিপেটটি চেষ্টা করুন, যা আমি বর্তমানে আমার নিজের কনফিগারেশনে ব্যবহার করছি:

# Deduplicate path variables
get_var () {
    eval 'printf "%s\n" "${'"$1"'}"'
}
set_var () {
    eval "$1=\"\$2\""
}
dedup_pathvar () {
    pathvar_name="$1"
    pathvar_value="$(get_var "$pathvar_name")"
    deduped_path="$(perl -e 'print join(":",grep { not $seen{$_}++ } split(/:/, $ARGV[0]))' "$pathvar_value")"
    set_var "$pathvar_name" "$deduped_path"
}
dedup_pathvar PATH
dedup_pathvar MANPATH

এই কোডটি পাঠ এবং মনপথ উভয়ই নকল করবে এবং আপনি সহজেই dedup_pathvarঅন্যান্য ভেরিয়েবলগুলিতে কল করতে পারেন যা কোলন-বিচ্ছিন্ন পাথের তালিকা রাখে (যেমন পাইথোনপথ)।


কোনও কারণে আমাকে chompএকটি পেছনের নিউলাইন সরানোর জন্য একটি যুক্ত করতে হয়েছিল। এটি আমার পক্ষে কাজ করেছে:perl -ne 'chomp; print join(":", grep { !$seen{$_}++ } split(/:/))' <<<"$PATH"
হ্যাকন হাগল্যান্ড

12

এখানে একটি স্নেহময়:

printf %s "$PATH" | awk -v RS=: -v ORS=: '!arr[$0]++'

দীর্ঘতর (এটি কীভাবে কাজ করে তা দেখতে):

printf %s "$PATH" | awk -v RS=: -v ORS=: '{ if (!arr[$0]++) { print $0 } }'

ঠিক আছে, যেহেতু আপনি লিনাক্সে নতুন, তাই এখানে কোনও লেজ ছাড়াই কীভাবে PATH সেট করবেন তা এখানে রয়েছে ":"

PATH=`printf %s "$PATH" | awk -v RS=: '{ if (!arr[$0]++) {printf("%s%s",!ln++?"":":",$0)}}'`

বিটিডাব্লু আপনার পাথের মধ্যে ":" ধারণকারী ডিরেক্টরি না রয়েছে তা নিশ্চিত করুন, অন্যথায় এটি গণ্ডগোল হবে।

কিছু ক্রেডিট:


-1 এটি কাজ করে না। আমি এখনও আমার পথে সদৃশ দেখতে পাই।
ডগবনে

4
@ ডগবেন: এটি আমার জন্য সদৃশগুলি সরিয়ে দেয়। তবে এটি একটি সূক্ষ্ম সমস্যা আছে। আউটপুটটির একটি রয়েছে: শেষে যা আপনার $ PATH হিসাবে সেট করা হয় তার অর্থ বর্তমান ডিরেক্টরিটি যুক্ত করা হয়েছে। এটি একটি বহু ব্যবহারকারী মেশিনে সুরক্ষা জড়িত imp
চাঁদ

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

@ ডগবনে আপনার সমাধানটির পিছনে দিক রয়েছে: আউটপুটে
আকস্তাদদিনভ

হুঁ, আপনার তৃতীয় কমান্ডটি কাজ করে তবে প্রথমটি দু'টি কাজ না করে আমি ব্যবহার না করি echo -n। আপনার কমান্ডগুলি "এখানে স্ট্রিং" দিয়ে কাজ করছে বলে মনে হচ্ছে না, যেমন: চেষ্টা করুন:awk -v RS=: -v ORS=: '!arr[$0]++' <<< ".:/foo/bin:/bar/bin:/foo/bin"
ডগবনে

6

এখানে একটি AWK ওয়ান লাইনার রয়েছে।

$ PATH=$(printf %s "$PATH" \
     | awk -vRS=: -vORS= '!a[$0]++ {if (NR>1) printf(":"); printf("%s", $0) }' )

কোথায়:

  • printf %s "$PATH"$PATHকোনও পেছনের নিউলাইন ছাড়াই লিখিত সামগ্রী মুদ্রণ করে
  • RS=: ইনপুট রেকর্ড ডিলিমিটার অক্ষর পরিবর্তন করে (ডিফল্টটি নতুন লাইন হয়)
  • ORS= আউটপুট রেকর্ড ডিলিমেটারকে খালি স্ট্রিংয়ে পরিবর্তন করে
  • a একটি সুস্পষ্টভাবে তৈরি অ্যারের নাম
  • $0 বর্তমান রেকর্ড রেফারেন্স
  • a[$0] একটি সহযোগী অ্যারে ডিরিফারেন্স
  • ++ পোস্ট-ইনক্রিমেন্ট অপারেটর
  • !a[$0]++ ডান হাত রক্ষা করে, অর্থাত্ এটি নিশ্চিত করে যে বর্তমান রেকর্ডটি কেবল মুদ্রিত হয়েছে, যদি এটি আগে প্রিন্ট না করা হত
  • NR বর্তমান রেকর্ড নম্বর, 1 দিয়ে শুরু

এর অর্থ হ'ল এডাব্লুকে ডিলিমিটার অক্ষরগুলির PATHসাথে কন্টেন্টটি বিভক্ত করতে :এবং ক্রম পরিবর্তন না করে নকল প্রবেশগুলি ছাঁটাই করতে ব্যবহৃত হয় out

যেহেতু এডাব্লুকে এসোসিয়েটিভ অ্যারেগুলি হ্যাশ টেবিল হিসাবে প্রয়োগ করা হয় রানটাইমটি রৈখিক হয় (যেমন ও (এন) এ)।

নোট করুন যে আমাদের উদ্ধৃত :অক্ষরগুলির সন্ধানের দরকার নেই কারণ শেলগুলি ভেরিয়েবলের :নামের সাথে ডিরেক্টরিগুলি সমর্থন করার জন্য উদ্ধৃতি সরবরাহ করে নাPATH

ওও + পেস্ট

উপরেরগুলি পেস্ট দিয়ে সহজ করা যেতে পারে:

$ PATH=$(printf %s "$PATH" | awk -vRS=: '!a[$0]++' | paste -s -d:)

pasteকমান্ড কোলন সঙ্গে awk আউটপুট ছড়ান করতে ব্যবহৃত হয়। এটি মুদ্রণ (যা ডিফল্ট ক্রিয়া) এ অবাক ক্রিয়াকে সহজতর করে।

পাইথন

পাইথন টু-লাইনারের সমান:

$ PATH=$(python3 -c 'import os; from collections import OrderedDict; \
    l=os.environ["PATH"].split(":"); print(":".join(OrderedDict.fromkeys(l)))' )

ঠিক আছে, তবে এটি কি কোনও বিদ্যমান কোলনের সীমানাযুক্ত স্ট্রিং থেকে ডুপস সরিয়ে দেয়, বা এটি স্টুপে ডুপস যুক্ত হতে বাধা দেয়?
আলেকজান্ডার মিলস

1
পূর্বের মত দেখাচ্ছে
আলেকজান্ডার মিলস

2
@ আলেকজান্ডারমিলস, ঠিক আছে, ওপি ডুপ্লিকেটগুলি সরিয়ে দেওয়ার বিষয়ে জিজ্ঞাসা করেছিল তাই এআরজি কলটি এটি করে।
maxschlepzig

1
pasteকমান্ড আমার জন্য কাজ করে না, যদি না আমি একটি trailing যোগ -stdin ব্যবহার করতে।
উইসবাকি

2
এছাড়াও, আমার পরে স্পেস যুক্ত করা দরকার -vঅন্যথায় আমি একটি ত্রুটি পেয়েছি। -v RS=: -v ORS=awkসিনট্যাক্সের বিভিন্ন স্বাদ মাত্র ।
উইসবাকি

4

এখানে এই সম্পর্কে একই আলোচনা হয়েছে

আমি কিছুটা আলাদা পন্থা নিই। ইনস্টল হওয়া সমস্ত পৃথক সূচনা ফাইলগুলির মধ্যে সেট করা প্যাথটিকে কেবল গ্রহণ করার পরিবর্তে, আমি getconfসিস্টেমের পাথ চিহ্নিত করতে এবং এটি প্রথমে স্থাপন করতে পছন্দ করি, তারপরে আমার পছন্দসই পাথ ক্রম যুক্ত করুন, তারপরে awkযেকোন সদৃশগুলি সরিয়ে ফেলতে ব্যবহার করুন । এটি কমান্ড কার্যকর করার ক্ষেত্রে বা তাত্পর্যপূর্ণ হতে পারে (এবং তাত্ত্বিকভাবে আরও সুরক্ষিত) তবে এটি আমাকে উষ্ণ ফাজি দেয়।

# I am entering my preferred PATH order here because it gets set,
# appended, reset, appended again and ends up in such a jumbled order.
# The duplicates get removed, preserving my preferred order.
#
PATH=$(command -p getconf PATH):/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
# Remove duplicates
PATH="$(printf "%s" "${PATH}" | /usr/bin/awk -v RS=: -v ORS=: '!($0 in a) {a[$0]; print}')"
export PATH

[~]$ echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/lib64/ccache:/usr/games:/home/me/bin

3
এটি খুবই বিপজ্জনক কারণ আপনার একটি trailing যোগ :করার PATH, (অর্থাত একটি খালি স্ট্রিং এন্ট্রি) কারণ তারপর বর্তমান কাজ ডিরেক্টরির আপনার অংশ PATH
maxschlepzig

3

যতক্ষণ না আমরা অ-অব্ক অনেলাইনারগুলি যুক্ত করব:

PATH=$(zsh -fc "typeset -TU P=$PATH p; echo \$P")

(এর মতো সহজ হতে পারে PATH=$(zsh -fc 'typeset -U path; echo $PATH')তবে zsh সর্বদা কমপক্ষে একটি zshenvকনফিগারেশন ফাইল পড়ে, যা পরিবর্তন করতে পারে PATH))

এটি দুটি দুর্দান্ত zsh বৈশিষ্ট্য ব্যবহার করে:

  • অ্যারেতে বাঁধা স্কেলার ( typeset -T)
  • এবং অ্যারেগুলি যা সদৃশ মানগুলিকে ( typeset -U) মানায় ।

চমৎকার! সংক্ষিপ্ত পরিশ্রমী উত্তর, এবং স্থানীয়ভাবে শেষে কোলন ছাড়াই।
japap

2
PATH=`perl -e 'print join ":", grep {!$h{$_}++} split ":", $ENV{PATH}'`
export PATH

এটি পার্ল ব্যবহার করে এবং এর বিভিন্ন সুবিধা রয়েছে:

  1. এটি সদৃশগুলি সরিয়ে দেয়
  2. এটি সাজানোর ক্রম রাখে
  3. এটি প্রথম দিকের উপস্থিতি রাখে ( /usr/bin:/sbin:/usr/binফলাফল হবে /usr/bin:/sbin)

2

এছাড়াও sed(এখানে জিএনইউ sedসিনট্যাক্স ব্যবহার করে ) কাজটি করা যেতে পারে:

MYPATH=$(printf '%s\n' "$MYPATH" | sed ':b;s/:\([^:]*\)\(:.*\):\1/:\1\2/;tb')

এই পথটি কেবলমাত্র .ডগবানের উদাহরণের মতো হলে ভাল কাজ করে ।

সাধারণ ক্ষেত্রে আপনাকে আরও একটি sকমান্ড যুক্ত করতে হবে :

MYPATH=$(printf '%s\n' "$MYPATH" | sed ':b;s/:\([^:]*\)\(:.*\):\1/:\1\2/;tb;s/^\([^:]*\)\(:.*\):\1/:\1\2/')

এটি এমন নির্মাণেও কাজ করে:

$ echo "/bin:.:/foo/bar/bin:/usr/bin:/foo/bar/bin:/foo/bar/bin:/bar/bin:/usr/bin:/bin" \
| sed ':b;s/:\([^:]*\)\(:.*\):\1/:\1\2/;tb;s/^\([^:]*\)\(:.*\):\1/\1\2/'

/bin:.:/foo/bar/bin:/usr/bin:/bar/bin

2

অন্যরা যেমন দেখিয়েছে যে এটি এক লাইনে awk, সেড, পার্ল, জেডএস, বা ব্যাশ ব্যবহার করে দীর্ঘ লাইন এবং পঠনযোগ্যতার জন্য আপনার সহনশীলতার উপর নির্ভর করে। এখানে একটি বাশ ফাংশন

  • সদৃশ অপসারণ
  • অর্ডার সংরক্ষণ করে
  • ডিরেক্টরি নাম ফাঁকা করার অনুমতি দেয়
  • আপনাকে ডিলিমিটার নির্দিষ্ট করতে দেয় (':' এ ডিফল্ট)
  • শুধু পাঠ নয়, অন্যান্য ভেরিয়েবলের সাথে ব্যবহার করা যেতে পারে
  • বাশ সংস্করণ <4 এ কাজ করে, গুরুত্বপূর্ণ যদি আপনি ওএস এক্স ব্যবহার করেন যা লাইসেন্স সংক্রান্ত সমস্যাগুলির জন্য বাশ সংস্করণ 4 প্রেরণ করে না

বাশ ফাংশন

remove_dups() {
    local D=${2:-:} path= dir=
    while IFS= read -d$D dir; do
        [[ $path$D =~ .*$D$dir$D.* ]] || path+="$D$dir"
    done <<< "$1$D"
    printf %s "${path#$D}"
}

ব্যবহার

PATH থেকে ডুপস সরানোর জন্য

PATH=$(remove_dups "$PATH")

1

এটি আমার সংস্করণ:

path_no_dup () 
{ 
    local IFS=: p=();

    while read -r; do
        p+=("$REPLY");
    done < <(sort -u <(read -ra arr <<< "$1" && printf '%s\n' "${arr[@]}"));

    # Do whatever you like with "${p[*]}"
    echo "${p[*]}"
}

ব্যবহার: path_no_dup "$PATH"

নমুনা আউটপুট:

rany$ v='a:a:a:b:b:b:c:c:c:a:a:a:b:c:a'; path_no_dup "$v"
a:b:c
rany$

1

সাম্প্রতিক ব্যাশ সংস্করণগুলি (> = 4) এছাড়াও সম্মিলিত অ্যারেগুলির, অর্থাত আপনি এটির জন্য একটি ব্যাশ 'ওয়ান লাইনার' ব্যবহার করতে পারেন:

PATH=$(IFS=:; set -f; declare -A a; NR=0; for i in $PATH; do NR=$((NR+1)); \
       if [ \! ${a[$i]+_} ]; then if [ $NR -gt 1 ]; then echo -n ':'; fi; \
                                  echo -n $i; a[$i]=1; fi; done)

কোথায়:

  • IFS ইনপুট ফিল্ড বিভাজককে পরিবর্তন করে :
  • declare -A একটি সহযোগী অ্যারে ঘোষণা করে
  • ${a[$i]+_}একটি প্যারামিটার সম্প্রসারণ অর্থ: _প্রতিস্থাপিত হয় যদি a[$i]সেট করা থাকে এবং কেবল তখনই । এটি অনুরূপ ${parameter:+word}যা নাল-পরীক্ষা করার জন্যও পরীক্ষা করে। সুতরাং, শর্তাধীন নিম্নলিখিত মূল্যায়নের মধ্যে, এক্সপ্রেশনটি _(অর্থাত্ একটি একক অক্ষরের স্ট্রিং) সত্যকে মূল্যায়ন করে (এটি সমান -n _) - যখন একটি খালি অভিব্যক্তি মিথ্যাতে মূল্যায়ন করে।

+1: দুর্দান্ত স্ক্রিপ্ট স্টাইল, তবে আপনি নির্দিষ্ট বাক্য গঠনটি ব্যাখ্যা করতে পারেন: ${a[$i]+_}নিজের উত্তর সম্পাদনা করে এবং একটি বুলেট যুক্ত করে। বাকিটি পুরোপুরি বোধগম্য তবে আপনি আমাকে সেখানে হারিয়েছেন। ধন্যবাদ.
সিবিহে

1
@ সিবিহে, আমি একটি বুলেট পয়েন্ট যুক্ত করেছি যা এই প্রসারকে সম্বোধন করে।
ম্যাক্সচলেপজিগ

আপনাকে অনেক ধন্যবাদ. অনেক আগ্রহব্যাঞ্জক. আমি ভাবিনি যে অ্যারে (অ-স্ট্রিং) দিয়ে এটি সম্ভব হয়েছিল ...
সিবিহে

1
PATH=`awk -F: '{for (i=1;i<=NF;i++) { if ( !x[$i]++ ) printf("%s:",$i); }}' <<< "$PATH"`

অ্যাজক কোডের ব্যাখ্যা:

  1. কলোন দ্বারা ইনপুট আলাদা করুন।
  2. দ্রুত ডুপ্লিকেট লুক-আপের জন্য সাহসী অ্যারেতে নতুন পাথ এন্ট্রি যুক্ত করুন App
  3. সহযোগী অ্যারে মুদ্রণ করে।

সংশ্লেষ ছাড়াও, এই ওয়ান-লাইনারটি দ্রুত: অ্যাওরওকে এমোরিটাইজড ও (1) সম্পাদন করতে একটি চেইনিং হ্যাশ-টেবিল ব্যবহার করে।

সদৃশ $ PATH এন্ট্রি সরানোর উপর ভিত্তি করে


পুরানো পোস্ট, কিন্তু আপনি ব্যাখ্যা করতে পারে: if ( !x[$i]++ )। ধন্যবাদ।
সিবিহে

0

awkপাথটি বিভক্ত করতে ব্যবহার করুন :, তারপরে প্রতিটি ক্ষেত্রের উপর লুপ করুন এবং এটি অ্যারেতে সঞ্চয় করুন। যদি আপনি এমন কোনও ক্ষেত্র জুড়ে এসে থাকেন যা ইতিমধ্যে অ্যারেতে রয়েছে, এর অর্থ আপনি এটি আগে দেখেছেন, তাই এটি মুদ্রণ করবেন না।

এখানে একটি উদাহরণ:

$ MYPATH=.:/foo/bar/bin:/usr/bin:/foo/bar/bin
$ awk -F: '{for(i=1;i<=NF;i++) if(!($i in arr)){arr[$i];printf s$i;s=":"}}' <<< "$MYPATH"
.:/foo/bar/bin:/usr/bin

(ট্রেলিং অপসারণের জন্য আপডেট করা হয়েছে :))


0

একটি সমাধান - এটি যে * আরএস ভেরিয়েবলগুলি পরিবর্তন করে তাদের মত মার্জিত নয়, তবে সম্ভবত যুক্তিযুক্তভাবে পরিষ্কার:

PATH=`awk 'BEGIN {np="";split(ENVIRON["PATH"],p,":"); for(x=0;x<length(p);x++) {  pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np ":"; np=np pe}} END { print np }' /dev/null`

পুরো প্রোগ্রামটি বিগইন এবং এন্ড ব্লকগুলিতে কাজ করে। এটি পরিবেশ থেকে আপনার PATH ভেরিয়েবলটি টানছে, একে ইউনিটে বিভক্ত করে। এরপরে এটি ফলাফল অ্যারে পি (যা দ্বারা ক্রমে তৈরি করা হয় split()) এর পুনরাবৃত্তি হয় । অ্যারে একটি সহযোগী অ্যারে যা আমরা বর্তমান পথের উপাদানটি (যেমন / usr / স্থানীয় / বিন ) এর আগে দেখেছি কিনা এবং তা নির্ধারণ করতে ব্যবহৃত হয় , এবং যদি না হয় তবে এনপি-তে সংযুক্ত করা হয়েছে , কোলনে যুক্ত করার যুক্তি যুক্ত রয়েছে NP যদি ইতিমধ্যেই লেখা NPEND টি ব্লক কেবল এত প্রতিধ্বনি NP । যোগ করে এটি আরও সরল করা যেতে পারে-F:পতাকা, তৃতীয় যুক্তি দূর split()(যেমন ডিফল্ট ফাঃ ), এবং পরিবর্তন np = np ":"করার জন্য np = np FS, আমাদের দান:

awk -F: 'BEGIN {np="";split(ENVIRON["PATH"],p); for(x=0;x<length(p);x++) {  pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np FS; np=np pe}} END { print np }' /dev/null

অবশ্যই, আমি বিশ্বাস করি যে এটি for(element in array)অর্ডার সংরক্ষণ করবে, কিন্তু এটি কার্যকর হয় না, সুতরাং আমার আসল সমাধানটি কাজ করে না, কারণ হঠাৎ যদি কেউ তাদের ক্রমটি ভ্রষ্ট করে দেয় তবে লোকেরা বিচলিত হবে $PATH:

awk 'BEGIN {np="";split(ENVIRON["PATH"],p,":"); for(x in p) { pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np ":"; np=np pe}} END { print np }' /dev/null

0
export PATH=$(echo -n "$PATH" | awk -v RS=':' '(!a[$0]++){if(b++)printf(RS);printf($0)}')

শুধুমাত্র প্রথম ঘটনাটি রাখা হয় এবং আপেক্ষিক অর্ডারটি ভালভাবে বজায় থাকে।


-1

আমি কেবল টিআর, বাছাই এবং ইউনিকের মতো প্রাথমিক সরঞ্জামগুলি দিয়ে এটি করব:

NEW_PATH=`echo $PATH | tr ':' '\n' | sort | uniq | tr '\n' ':'`

আপনার পথে যদি বিশেষ বা অদ্ভুত কিছু না থাকে তবে এটি কাজ করা উচিত


বিটিডব্লিউ, আপনি এর sort -uপরিবর্তে ব্যবহার করতে পারেন sort | uniq
ভিড়ের

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