बैश: स्टैडआउट में अंतिम (या Nth) लाइन कैप्चर / उपयोग करें


11

सवाल

मैं बैश का उपयोग करता हूं। जब मैं फ़ाइलों की तलाश कर रहा हूं, तो अक्सर मैं निम्नलिखित कार्य करूंगा:

find -name stackexchange.hs

और अक्सर परिणाम इस तरह दिखेंगे:

/youre/the/man/now/dog/stackexchange.hs
/you/are/no/longer/the/dog/dog/stackexchange.hs
/this/is/the/file/i/want/stackexchange.hs

फिर मैं निम्नलिखित में से एक करना चाहता हूँ:

  • विकल्प 1: में परिणामों की सूची में अंतिम आइटम खोलें vim
  • विकल्प 2: में परिणामों की सूची में ओपन वां आइटम vim

वर्तमान में, मैंने माउस से कट-एंड-पेस्ट किया। जो मुझे मेरे सवाल पर लाता है :

  1. क्या विकल्प 1 और 2 को पूरा करने के लिए एक आसान, एक-लाइनर है? ध्यान दें कि यह कमांड के बाद हो रहा है find
  2. क्या किसी तरह के बैश वेक्टर / सरणी में stdout से एन-लाइनों को पकड़ने का एक तरीका है?

आदर्श उपयोग

$ find -name am_i_really_all_alone.txt
./borges/library/you_are_not_alone.txt
./borges/library/am_i_really_all_alone.txt
$ vim (N)

(वाक्य रचना और शब्दार्थ भिन्न हो सकते हैं, लेकिन आपको यह बात मिलती है)

Similaria

ऐसे ही कई सवाल लगते हैं। यहाँ मेरे कथित मतभेद हैं (मैं आत्मज्ञान के लिए खुला हूँ):

आपके सहयोग के लिए धन्यवाद! 90 के दशक में जब मैं किशोर था तब * nix / BSD का उपयोग कर रहा था और मेरे प्लग-एंड-प्ले साउंड कार्ड के लिए ड्राइवरों को स्थापित करने में मेरी मदद करने के लिए अपने बर्नआउट, एसिड-हेड पड़ोसी को फोन करके डर गया था, मैं कमांड पर चर्चा करने के लिए राहत महसूस कर रहा हूं- कम से कम भयावह व्यक्तियों के साथ लाइन minutiae। वापस आना बहुत अच्छा लग रहा है।


मुझे लगता है, कि यदि आप इसे पहले जानते हैं कि आप अंतिम परिणाम खोलना चाहते हैं, तो आप कुछ का उपयोग कर सकते हैं vim $(command |tail -n1)
वरेसा

मैंने यहाँ एक समान प्रश्न पोस्ट किया unix.stackexchange.com/questions/348224/…
joelostblom

जवाबों:


8

यहां आपके मुद्दे का एक संभावित समाधान है जो यथोचित होना चाहिए (लेकिन पूरी तरह से नहीं है) कायरता फ़ाइल नामों की उपस्थिति में सुरक्षित (उन में फीडफ़ेन्स के साथ फाइलनेम को संभालना नहीं है - शायद निर्धारण योग्य है, लेकिन अन्य समस्याएँ भी हो सकती हैं)।

दो फ़ंक्शंस, पहला जो findआप इसे पास करते हैं, उसके साथ चलता है, आउटपुट को एरे में सेव करता है, और उन्हें प्रदर्शित करता है। दूसरा उस सरणी तक पहुंचने के लिए सिर्फ एक सहायक है।

myfind() {
  IFS=$'\n' __last_find_result=($(find "$@"));
  printf "%s\n" "${__last_find_result[@]}";
}
myget() {
  echo "${__last_find_result[$1]}";
}

उदाहरण:

$ myfind . -name "c*"
./a b/c d
./.git/config
./.git/hooks/commit-msg.sample
$ vim "$(myget 0)"
# This opens the "./a b/c d" file.
$ vim "$(myget 2)"
# This opens ".git/hooks/commit-msg.sample"

$(myget index)यदि आपके व्हाट्सएप में व्हाट्सएप या अन्य परेशानी वाले पात्र नहीं हैं , तो उद्धरण आवश्यक नहीं है। आपके पर्यावरण
के पूरे आउटपुट को धक्का देता findहै, जो सीमित हो सकता है। (उस सरणी के बजाय एक अस्थायी फ़ाइल का उपयोग करने से यह हल हो जाएगा, लेकिन अन्य मुद्दे हैं - विशेष रूप से कई शेल से समवर्ती उपयोग।)


1
मैं तुम्हें उभार नहीं सकता क्योंकि मेरे पास प्रतिष्ठा नहीं है, इसलिए यहाँ एक, उह, मौखिक एक है: "
अपवोट

6

मुझे यह मेरे में मिला है .screenrc:

bind -c pasteline 1 eval copy 'stuff "-Y"' 'paste .'
bind -c pasteline 2 eval copy 'stuff "2-Y"' 'paste .'
bind -c pasteline 3 eval copy 'stuff "3-Y"' 'paste .'
bind -c pasteline 4 eval copy 'stuff "4-Y"' 'paste .'
bind -c pasteline 5 eval copy 'stuff "5-Y"' 'paste .'
bind -c pasteline 6 eval copy 'stuff "6-Y"' 'paste .'
bind -c pasteline 7 eval copy 'stuff "7-Y"' 'paste .'
bind -c pasteline 8 eval copy 'stuff "8-Y"' 'paste .'
bind -c pasteline 9 eval copy 'stuff "9-Y"' 'paste .'
bindkey ¬ command -c pasteline

असल में, स्क्रीन में, ¬1कर्सर के ऊपर लाइन को पेस्ट करता है,, कर्सर के ¬2ऊपर दूसरी लाइन को चिपकाता है ... और इसी तरह। आप लाइनों 10 और ऊपर के लिए और अधिक जोड़ना चाहते हैं, लेकिन मुझे लगता है कि पहले से ही लगभग 7 के बाद, मैं माउस या screenकॉपी मोड का उपयोग करना चाहूंगा, जिससे मैं चाहता हूं कि लाइनों की संख्या की गणना की जा सके।


0

एक और उपाय है: आप एक इंटरैक्टिव स्क्रिप्ट लिख सकते हैं जो स्वचालित रूप से आपकी पसंद पूछेगा। यहाँ इंटरैक्टिव स्क्रिप्ट के लिए कोड है:

#!/bin/bash

echo "enter your choice : z for last argument or a number for that file"
read choice

case "$choice" in
z) eval vim \$$#;;
*)eval  vim \$$choice;;
esac

किसी भी नाम के साथ इस स्क्रिप्ट को "ऑटोफ़ाइंड" कहने के लिए सहेजें और अपने "कमांड ढूंढें" के साथ स्क्रिप्ट को लागू करें क्योंकि तर्क यहाँ स्क्रिप्ट को आमंत्रित करने के लिए कोड है:

./autofind `your find command`

लेकिन स्क्रिप्ट का उपयोग करने से पहले अपने "find कमांड" की जांच करें कि क्या यह परिणाम दे रहा है या नहीं। यदि यह कुछ परिणाम दिखा रहा है तो केवल स्क्रिप्ट का उपयोग करें


0

मैट का जवाब सिर्फ वही था जिसकी मुझे तलाश थी। मैंने और अधिक विकल्प प्राप्त करने की अनुमति देने के लिए उनके कोड का थोड़ा विस्तार किया है।

$ f ~/scripts -name '*.sh'
$ vim $(g foo)  # edit all find results matching "foo"
$ vim $(g 1 3 5) # edit find results number 1, 3 and 5
$ vim $(g 3-5) # edit find results 3-5
$ vim $(g 5-) # edit find results 5 to last
$ vim $(g -7) # edit find result 7 from bottom
$ vim $(g 1 4-5 -7 9- foo) # all of the above combined

f() {
    IFS=$'\n' __last_find_result=($(find "$@"));
    printf "%s\n" "${__last_find_result[@]}";
}

g() {
    len=${#__last_find_result[@]}
    pad=${#len}
    numbers=""
    if [ "$1" == "-n" ]; then
        numbers=1
        shift
    fi
    if [ -z "$1" ]; then
        if [ -n "$numbers" ]; then
            n=1;
            for e in "${__last_find_result[@]}";do
                printf "%0${pad}d. %s\n" "$n" "$e"
                let n=n+1
            done
        else
            printf "%s\n" "${__last_find_result[@]}"
        fi
    else
        for l in $@;do
            if [[ "$l" =~ ([^0-9-]+) ]];then
                n=1;
                for e in "${__last_find_result[@]}";do
                    if [[ $e =~ $1 ]]; then
                        if [ -n "$numbers" ];then
                            printf "%0${pad}d. %s\n" "$n" "$e"
                        else
                            printf "%s\n" "$e"
                        fi
                    fi
                    let n=n+1
                done
            elif [[ "$l" =~ ^([0-9]+)$ ]];then
                let l=l-1
                echo "${__last_find_result[$l]}";
            elif [[ "$l" =~ ^([0-9]*)(-)?([0-9]*)$ ]]; then
                from=${BASH_REMATCH[1]};
                dash=${BASH_REMATCH[2]};
                to=${BASH_REMATCH[3]};
                if [ -z "$from" ]; then # -n
                    [ $to -gt ${#__last_find_result[@]} ] && to=${#__last_find_result[@]}
                    echo "${__last_find_result[-$to]}";
                else # n-m
                    [ -z "$to" ] && to=${#__last_find_result[@]}
                    [ $to -gt ${#__last_find_result[@]} ] && to=${#__last_find_result[@]}
                    let to=$to-1
                    let from=$from-1
                    n=$(($from+1))
                    for i in `seq $from $to`;do
                        if [ -n "$numbers" ];then
                            printf "%0${pad}d. %s\n" "$n" "${__last_find_result[$i]}"
                        else
                            printf "%s\n" "${__last_find_result[$i]}"
                        fi
                        let n=n+1
                    done
                fi
            fi
        done
    fi
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.