শেষে ফাঁকা লাইন নেই এমন ফাইলগুলি কীভাবে সন্ধান করবেন?


9

আমার কাছে বর্তমান ডিরেক্টরিটির উপ-ডিরেক্টরিতে ফাইল রয়েছে যা শেষে নতুন লাইন থাকতে পারে বা নাও থাকতে পারে; শেষের দিকে একটি নতুন লাইন নেই এমন ফাইলগুলি আমি কীভাবে খুঁজে পাব?

আমি এটি চেষ্টা করেছি:

find . -name '*.styl' | while read file; do
    awk 'END{print}' $file | grep -E '^$' > /dev/null || echo $file;
done

কিন্তু এটি কাজ করে না। awk 'END{print}' $fileএকটি খালি নতুন লাইন সামনে লাইন, হিসাবে একই ছাপে tail -n 1 $file


@ don_crissti আমার কাছে এমন ফাইলের দরকার আছে যেগুলি খালি লাইনে অনুসরণ করবে না।
jcubic

2
আপনার এই ফাইলগুলি সন্ধান করার প্রয়োজনীয় কারণটি আমি জিজ্ঞাসা করতে পারি? আমি অনুমান করি যে এটির সাথে ইউনিক্সের পাঠ্য ফাইলগুলি একটি নতুন লাইন দিয়ে শেষ করা উচিত (যেমন আপনি যখন সংরক্ষণ করবেন তখন vi প্রায় "নিঃশব্দে" যুক্ত করবে), এবং বেশ কয়েকটি (পাঠ্য -মুখী) আদেশগুলি উপেক্ষা করবে শেষ লাইনটি যদি এটি একটি নতুন লাইন দ্বারা বন্ধ না করা হয় (ডাব্লুসি, আইরিক .... তবে অন্যরা রয়েছে)। এবং এটি সাহায্য করতে পারে
অলিভিয়ার ডুলাক

awk 'END{print}' $file : এটি সম্পূর্ণরূপে $ ফাইলের বিষয়বস্তু উপেক্ষা করে এবং "$ ফাইল" এর মধ্যে থাকা সমস্ত ফাইল বিশ্লেষণ শেষ করে এটি একটি নতুন লাইন যুক্ত করে। যেহেতু এটি শুধুমাত্র awk কমান্ড মুদ্রণ করে তাই এটি প্রতিস্থাপন করা যেতে পারে: printf '\n'($ ফাইলের কোনও মেন্টিনো ছাড়াই) এবং একই জিনিসটি করুন। আমি মনে করি আপনি এটি লক্ষ্য করছেন তা নয় (উদাহরণস্বরূপ: ফাইলটির শেষ লাইনটি মুদ্রণ করুন?)
অলিভিয়ার ডুলাক

@ ডন_ক্রিসটি: কোনও ফাইলের শেষ চরিত্রটি যদি নতুন লাইন না হয় তবে সেই ফাইলটি কঠোরভাবে একটি ইউনিক্স টেক্সট ফাইল নয়। দেখুন: unix.stackexchange.com/a/263919/27616 । নোট করুন যে অনেকগুলি টেক্সট কমান্ড (উদাহরণস্বরূপ, উদাহরণস্বরূপ) যদি কোনও নতুন লাইনে এটি শেষ না করা হয় তবে শেষের "লাইন" উপেক্ষা করুন
অলিভিয়ার ডুলাক

1
@ অলিভারডুলাক: ফোকাস প্রিন্টগুলি cএবং ফ্রিবিএসডিও করে, তবে আমি এটি লক্ষ্য করি নি যে এটি বাস্তবায়ন-নির্ভর হিসাবে নথিভুক্ত: gnu.org/software/gawk/manual/… । সুতরাং এটি নেই ঘটতে তবে সব সময় নয়।
dave_thompson_085

উত্তর:


14

পরিষ্কার করার জন্য, এলএফ (ওরফে \nবা নিউলাইন) অক্ষরটি লাইন ডিলিমিটার , এটি লাইন বিভাজক নয়। নতুন লাইন চরিত্র দ্বারা শেষ না করা অবধি একটি লাইন শেষ হয় না। কেবলমাত্র a\nbএকটি ফাইলই বৈধ পাঠ্য ফাইল নয় কারণ এতে শেষ লাইনের পরে অক্ষর রয়েছে। কেবলমাত্র এমন ফাইলের জন্য একই a। একটি ফাইল যা একটি a\nখালি খালি লাইন ধারণ করে।

সুতরাং এমন একটি ফাইল যা কমপক্ষে একটি খালি রেখার সাথে শেষ হয় দুটি নিউলাইন অক্ষরের সাথে শেষ হয় বা এতে একটি নতুন লাইনের অক্ষর থাকে।

এমন:

 tail -c 2 file | od -An -vtc

আউটপুট \nবা \n \n, তারপরে ফাইলটিতে কমপক্ষে একটি ট্রেলিং খালি লাইন থাকে। যদি এটি কিছু না করে, তবে এটি একটি খালি ফাইল, যদি এটি আউটপুট করে <anything-but-\0> \n, তবে এটি একটি খালি ফাঁকা লাইনে শেষ হয়। অন্য কিছু, এটি কোনও পাঠ্য ফাইল নয়।

এখন, খালি লাইনে শেষ হওয়া ফাইলগুলি খুঁজে পেতে এটি ব্যবহার করতে, ঠিক আছে যে দক্ষ (বিশেষত বড় ফাইলগুলির জন্য) এটি কেবলমাত্র ফাইলগুলির শেষ দুটি বাইট পড়ে, তবে প্রথমে আউটপুট সহজেই পার্সেবল প্রোগ্রামিয়ালিটি বিশেষত বিবেচনা করে বিবেচনা করা যায় না একের প্রয়োগ থেকে odপরবর্তীটিতে সামঞ্জস্যপূর্ণ নয় এবং আমাদের প্রতি ফাইলের জন্য একটি tailএবং এক চালানো দরকার od

find . -type f -size +0 -exec gawk '
  ENDFILE{if ($0 == "") print FILENAME}' {} +

(খালি লাইনে শেষ হওয়া ফাইলগুলি সন্ধান করতে) যতটা সম্ভব কমান্ড চালানো হবে তবে এর অর্থ সমস্ত ফাইলের সম্পূর্ণ সামগ্রী পড়া।

আদর্শভাবে, আপনার একটি শেল লাগবে যা কোনও ফাইলের শেষে নিজেই পড়তে পারে।

সহ zsh:

zmodload zsh/system
for f (**/*(D.L+0)) {
  {
    sysseek -w end -2
    sysread
    [[ $REPLY = $'\n' || $REPLY = $'\n\n' ]] && print -r -- $f
  } < $f
}

এই ফাইলের উত্তরের পদ্ধতিটি ব্যবহার করার জন্য কিছু ফাইল (গুলি) টেক্সট ফাইল কিনা তা জানতে are_textfiles () { nontext=0; rem="return 0 if all args are files with terminating newline, or n [=number of non-textfiles]" ; for f in "$@" ; do [ -f "$f" ] && { tail -c 1 "$f" | od -An -vtc | grep "\\n" ;} >/dev/null 2>&1 || ((nontext++)) ; done ; return $nontext ; }। হিসাবে ব্যবহার করুন:if ( are_textfiles this that otherthing ) ; then echo all are text files ; else echo "are_textfiles returned : $?" ; fi
অলিভিয়ার ডুলাক

6

সহ gnu sedএবং একটি শেল এর মতো zsh(বা bashসাথে shopt -s globstar):

sed -ns '${/./F}' ./**/*.styl

প্রতিটি ফাইলের শেষ লাইনটি খালি না থাকলে এই ফাইলটি পরীক্ষা করে যদি এটি পরীক্ষা করে।
যদি আপনি বিপরীতে চান (শেষ লাইনটি ফাঁকা থাকে তবে ফাইলের নাম মুদ্রণ করুন) কেবল /./সাথে প্রতিস্থাপন করুন/^$/


1
এর -sআগে কখনও অ্যাকশনে দেখা যায়নি । আপনাকে জিএনইউ ধন্যবাদ!
গ্লেন জ্যাকম্যান

দ্রষ্টব্য: এফ বিকল্পটি সেড সংস্করণ 4.2.2 (ডিসেম্বর 22, 2012) থেকে উপস্থিত রয়েছে
আইজাক

3

একটি খালি শেষ লাইন সহ একটি সঠিকভাবে সমাপ্ত টেক্সট ফাইল দুটিতে শেষ হয় \n

তারপরে, আমরা আশা করি এটি tail -c2অবশ্যই সমান হবে $'\n\n'

দুঃখের সাথে কমান্ড বিস্তৃতি নতুন লাইনগুলি অনুসরণ করে remove আমাদের কিছুটা টুইট করার দরকার হবে।

f=filename
nl='
'
t=$(tail -c2 $f; printf x)  # capture the last two characters.
r="${nl}${nl}$"                 # regex for: "ends in two newlines".
[[ ${t%x} =~ $r ]] &&  echo "file $f ends in an empty line"

এমন কি নতুন ফাইলগুলি অনুমান করা যায় তা পরীক্ষা করতে আমরা কিছুটা প্রসারিত করতে পারি:

nl='
'
nl=$'\n'
find . -type f -name '*.styl' | while read f; do
    t=$(tail -c2 $f; printf x); r1="${nl}$"; r2="${nl}${r1}"
    [[ ${t%x} =~ $r1 ]] || echo "file $f is missing a trailing newline"
    [[ ${t%x} =~ $r2 ]] && echo "$f"
done

মনে রাখবেন যে নতুন লাইনটি $'\r\nপ্রয়োজনে এমন কিছুতে পরিবর্তন করা যেতে পারে ।
সেক্ষেত্রেও পরিবর্তন tail -c2করুন tail -c4


0
for file in *; do
    # Check if the file is readable to avoid clutter
    if cat "./$file" 2&>1 /dev/null; then
        # Compare the last character with a single newline character.
        if [ -n "$(tail -c 1 -- "./$file")" ]; then
            echo "$file"
        fi
        # Also report empty files.
        if [ $(wc -c  < "./$file") -eq 0 ]; then
            echo "$file"
        fi
    fi
done

1
এটি খালি ফাইলগুলির সাথে কাজ করে না তবে আমি এটি দিয়ে বেঁচে থাকতে পারি।
jcubic

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

আহ, এটি নতুন লাইনের চরিত্রগুলি উপেক্ষা করে।
ওসকার স্কোগ

আরও পঠনযোগ্য বিবেচনা করুন cat $file 2>&1 /dev/nullবা এটি কেবল বাশ-এর ​​জন্য হয় cat $file &> /dev/null
বিড়াল

1
এছাড়াও, $fileএটি ব্যবহৃত যেকোন জায়গায় উদ্ধৃতি বিবেচনা করুন - এবং দয়া করে এর $(commands ...)পরিবর্তে ব্যবহার করুন `backticks`...
বিড়াল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.