Awk প্রোগ্রামে পথ থেকে ফাইলের নাম বের করুন


21

আমার কাছে একটি অর্ড স্ক্রিপ্ট রয়েছে এবং আমি এটিতে একটি সিএসভি ফাইল পাস করেছি।

awk -f script.awk /home/abc/imp/asgd.csv

আমি যা করছি তা হ'ল ফাইল ফাইলের মধ্যে script.awk। FILENAME আমাকে পুরো পথ দেয়। আমি যেমন অবাক হয়েছি আমি ব্যবহার করতে পারি না basename FILENAME

print FILENAME;
/home/abc/imp/asgd.csv

আমি এর মধ্যে দিয়ে চেষ্টা করেছি script.awk

echo $FILENAME | awk -F"/" '{print $NF}'

তবে আমি এর মধ্যেই এটি কার্যকর করতে পারি না script.awk। আমি কীভাবে asgd.csvকোনও অর্ক প্রোগ্রামের মধ্যে পেতে পারি ?

উত্তর:


33

বিভিন্ন বিকল্প:

awk '
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

বা:

awk '
  function basename(file, a, n) {
    n = split(file, a, "/")
    return a[n]
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

নোট করুন যে সেগুলির বাস্তবায়নগুলি basenameসাধারণ ক্ষেত্রে কাজ করে তবে কোণের ক্ষেত্রে যেমন basename /path/to/x///তারা খালি স্ট্রিং পরিবর্তে ফিরে আসে xবা /যেখানে তারা খালি স্ট্রিংয়ের পরিবর্তে ফিরে আসে/ , যদিও নিয়মিত ফাইলগুলির ক্ষেত্রে এটি হওয়া উচিত নয়।

প্রথমটি সঠিকভাবে কাজ করবে না যদি ফাইল পাথগুলিতে (শেষ অবধি /) বাইটের ক্রম থাকে যা বর্তমান লোকালে বৈধ অক্ষর তৈরি করে না (সাধারণত এই জাতীয় জিনিসটি ইউটিএফ -8 স্থানীয় ফাইলগুলিতে কিছু 8 টিতে এনকোডযুক্ত থাকে) বিট একক বাইট অক্ষর সেট)। আপনি লোকেলটি সি-তে স্থির করে সেখানে কাজ করতে পারেন যেখানে বাইটের প্রতিটি ক্রম বৈধ অক্ষর গঠন করে।


5
আপনি কোড যে একটা ফাংশন প্রবর্তনের ছাড়া একটি বিদ্যমান awk স্ক্রিপ্ট মধ্যে সহজেই কাজ করবে প্রয়োজন হয়, আপনি ব্যবহার করা উচিত: n = split(FILENAME, a, "/"); basename=a[n];। এটি ব্যবহার করবেন না subযা আসলে FILENAMEভেরিয়েবল পরিবর্তন করবে (যা ফাংশনটির সাথে একটি নন-ইস্যু, যেহেতু অ্যাডাব্লু মান দ্বারা কল ব্যবহার করে)।
শিরি

10

এই বিশ্রী ওয়ান-লাইনার ব্যবহার করে দেখুন,

$ awk 'END{ var=FILENAME; split (var,a,/\//); print a[5]}' /home/abc/imp/asgd.csv
asgd.csv

3
বাawk 'END{ var=FILENAME; n=split (var,a,/\//); print a[n]}' /home/abc/imp/asgd.csv
অবিনাশ রাজ

0

এটিকে ইনপুট সিএসভি থেকে সরাসরি রপ্তানি করার সেরা উপায় বা সরাসরি ইনপুট ফাইল পাথ থেকে আপনি এটিকে বিপরীত করতে পারেন, তারপরে 1 কলাম পান এবং তারপরে আবার এটিকে বিপরীত করতে পারেন।

function getFileFromPath() {
    FileName=$1
    cat $FileName | while read Filename
    do
        echo $Filename| rev | awk -v FS='/' '{print $1}' | rev 
    done
}

বা সহজভাবে

echo $FileNamePath| rev | awk -v FS='/' '{print $1}' | rev 

0

আওকের স্প্লিট ফাংশন ব্যবহার করুন

এটি করার একটি উপায় হ'ল বিভক্ত ফাংশনটি ব্যবহার করা। উদাহরণ স্বরূপ:

awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' /path/to/file

এটি একাধিক ফাইলগুলিতেও কাজ করে। উদাহরণ স্বরূপ:

$ awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' \
      /etc/passwd /etc/group
passwd
group

0

basenameকমান্ড উপলভ্য সিস্টেমে বাহ্যিক কমান্ড কল করার জন্য কেউ awkএর system()ফাংশন বা expression | getline varকাঠামো ব্যবহার করতে পারে basename। এটি স্টিফেনের উত্তরে উল্লিখিত কোণার মামলার অ্যাকাউন্টিংয়ে সহায়তা করতে পারে ।

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.