2009-09-22 16 views
11

मैं निम्नलिखित समस्या से टकरा गई: फ़ाइल मार: स्ट्रिंग से पट्टी नई लाइन चरित्र (लाइन पढ़ें)

  • स्ट्रिप से

    • पढ़ें लाइन: मैं एक लिनक्स बैश स्क्रिप्ट जो निम्नलिखित करता है लिख रहा हूँ पंक्ति के अंत से \n चरित्र अभी-अभी पढ़ा
    • आदेश वहाँ में

    उदाहरण है कि निष्पादित करें: commands.txt

    ls 
    ls -l 
    ls -ltra 
    ps as 
    

    बैश फ़ाइल के निष्पादन के पहली पंक्ति मिलना चाहिए, और यह निष्पादित, लेकिन जब \n वर्तमान, खोल सिर्फ "नहीं मिला आदेश: ls" आउटपुट स्क्रिप्ट का वह भाग इस

    तरह लग रहा है
    read line 
    
         if [ -n "$line" ]; then #if not empty line 
    
           #myline=`echo -n $line | tr -d '\n'` 
           #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'` 
    
           myline=`echo -n $line | tr -d "\n"` 
           $myline #execute it 
    
           cat $fname | tail -n+2 > $fname.txt 
           mv $fname.txt $fname 
         fi 
    

    टिप्पणी की गई है कि आपके पास SO पूछने से पहले मैंने जो चीजें कोशिश की हैं। कोई समाधान? मैं इस घंटे से अधिक पिछले कुछ के लिए मेरे दिमाग स्मैश हूँ ...

  • +0

    आप बस अकेले '$ line' की कोशिश की? – knittl

    +0

    बेशक मैंने किया था। लेकिन यह कहता है "कमांड नहीं मिला: ls " –

    +0

    यह आवश्यक है कि: 'myline = "$ (echo -n" $ line ")" '(यदि आप चाहें तो' $() 'के बजाय बैकक्वॉट्स के साथ) – jnylen

    उत्तर

    17

    मुझे हमेशा न्यूलाइन को ट्रिम करने के लिए perl -ne 'chomp and print' पसंद है। अच्छा और याद रखने में आसान है।

    उदा ls -l | perl -ne 'chomp and print'

    हालांकि

    मुझे नहीं लगता कि यहां आपकी समस्या है, हालांकि है। हालांकि मुझे यकीन नहीं है कि मैं समझता हूं कि आप फ़ाइल में कमांड को अपनी शैल स्क्रिप्ट में 'पढ़ने' के माध्यम से कैसे पास कर रहे हैं।

    इस (test.sh) की तरह मेरे खुद की एक परीक्षण स्क्रिप्ट

    read line 
    if [ -n "$line" ]; then 
        $line 
    fi 
    

    और इस तरह एक नमूना इनपुट फ़ाइल के साथ (test.cmds)

    ls 
    ls -l 
    ls -ltra 
    

    तो मैं इसे इस तरह से चलाने के ./test.sh < test.cmds, मुझे अपेक्षित परिणाम दिखाई देता है, जो वर्तमान कार्य निर्देशिका पर पहला आदेश 'ls' चलाने के लिए है।

    शायद आपकी इनपुट फ़ाइल में इसमें अतिरिक्त गैर-प्रिंट करने योग्य वर्ण हैं?

    मेरा इस

    od -c test.cmds 
    0000000 l s  \n l s  - l \n l s  - l t 
    0000020 r a \n              
    0000023 
    

    नीचे अपनी टिप्पणी से की तरह दिखता है, मुझे लगता है कि आप अपने इनपुट फ़ाइल है, जो एक नई पंक्ति के रूप में एक ही बात नहीं है में कैरिएज रिटर्न ("\ r") हो सकता है। क्या इनपुट फ़ाइल मूल रूप से डॉस प्रारूप में है? यदि ऐसा है, तो आपको अपेक्षित परिणामों को प्राप्त करने के लिए "बाइट यूनिक्स", \ n "" \ n "को समाप्त करने वाली 2 बाइट डॉस लाइन को" \ r \ n "को परिवर्तित करने की आवश्यकता है।

    आपको अपनी किसी भी टिप्पणी लाइन में "\ r" के लिए "\ n" स्वैप करके ऐसा करने में सक्षम होना चाहिए।

    +1

    मैं यह उल्लेख करना भूल गया कि फ़ाइल एक सांबा शेयर में विंडोज से लिखी गई है और मैं पूरी तरह से भूल गया कि मुझे '\ n' के बजाय' \ r' की तलाश करनी चाहिए। मुझसे एक वोट और बहुत धन्यवाद! –

    2

    पर नहीं एक नज़र ls के लिए काम, मैं होने की सलाह देते है कि मैं इस की कोशिश की:

    read line 
    echo -n $line | od -x 
    

    इनपुट 'xxxx' के लिए, मैं मिलता है:

    0000000 7878 7878 
    

    जैसा कि आप देख सकते हैं, वहाँ है में कोई \n चर की सामग्री का अंत। मैं स्क्रिप्ट को -x (bash -x script) विकल्प के साथ चलाने का सुझाव देता हूं। यह सभी आदेशों को उनके द्वारा निष्पादित किए जाने पर मुद्रित करेगा।

    [संपादित करें] आपकी समस्या यह है कि आपने Windows पर command.txt संपादित किया है। अब, फ़ाइल में सीआरएलएफ (0 डी 0 ए) लाइन डिलीमीटर के रूप में है जो read (और ls\r ज्ञात कमांड नहीं है) को भ्रमित करता है। dos2unix का उपयोग करें या इसे यूनिक्स फ़ाइल में बदलने के समान।

    +0

    बात यह है कि मैं कीबोर्ड से नहीं पढ़ता हूं। मैं अपनी एसटीडीआईएन को एक फ़ाइल (उपरोक्त से कमांड.txt) में बदलता हूं और यदि मैं 'आउटपुट प्राप्त करता हूं' के बीच $ line को प्रतिबिंबित करता हूं तो ' –

    +0

    ' echo -n $ line 'पर प्राप्त आउटपुट। od -x' "0000000 736c 000d 0000003" –

    +1

    0 डी कैरिज रिटर्न है। एक नई बात – cms

    1

    आप eval आदेश की जरूरत है

    
    #!/bin/bash -x 
    
    while read cmd 
    do 
    if [ "$cmd" ] 
    then 
        eval "$cmd" 
    fi 
    done 
    

    मैं
    ./script.sh < file.txt

    के रूप में यह भाग गया और file.txt था:

     
    ls 
    ls -l 
    ls -ltra 
    ps as 
    
    +0

    'eval' भी काम नहीं करेगा –

    0

    निम्न स्क्रिप्ट काम करता है (कम से कम मेरे लिए):

    #!/bin/bash 
    
    while read I ; do if [ "$I" ] ; then $I ; fi ; done ; 
    
    12

    किसी ने पहले ही एक प्रोग्राम है जो खोल आदेशों को निष्पादित करता है लिखा है: श फ़ाइल

    आप वास्तव में केवल एक फ़ाइल की पहली पंक्ति पर अमल करना चाहते हैं: head -n 1 file |sh

    आपकी समस्या को गाड़ी-रिटर्न है: tr -d '\r' <file |sh

    +0

    हां, ज़ाहिर है, लेकिन मेरी बैच फ़ाइल का वह हिस्सा। यह फ़ाइल से एक साधारण निष्पादन कमांड से अधिक है, क्योंकि अगर यह केवल यही था तो मैंने निश्चित रूप से केवल 'sh' के लिए उपयोग किया है –

    2

    तुम भी नई-पंक्तियों केवल बैश builtins उपयोग करने के साथ कैरिएज रिटर्न को बदलने के लिए कोशिश कर सकते हैं:

    line=$'a line\r' 
    line="${line//$'\r'/$'\n'}" 
    #line="${line/%$'\r'/$'\n'}"  # replace only at line end 
    printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 
    
    संबंधित मुद्दे