Sed के साथ प्रसंस्करण बैश चर


16

बैश वेरिएबल LATLNG में ब्रैकेट्स में अक्षांश और देशांतर मान होता है

(53.3096,-6.28396)

मैं इन्हें LAT और LON नामक एक वैरिएबल में पार्स करना चाहता हूं, जिसे मैं sed जैसे करने की कोशिश कर रहा हूं

LAT=$(sed "s/(\(.*\),\(.*\))/\1/g" "$LATLNG")
LON=$(sed "s/(\(.*\),\(.*\))/\2/g" "$LATLNG")

हालाँकि, मुझे निम्न त्रुटि मिलती है:

sed: can't read (53.3096,-6.28396): No such file or directory


1
पायथन, रूबी, शायद यहां तक ​​कि PERL जैसी एक स्क्रिप्टिंग भाषा सीखें, ताकि आपको शेल को आपके लिए सब कुछ करने के लिए मजबूर न करना पड़े। तुम भी एक UNIX प्रणाली पर चलने के लिए जावास्क्रिप्ट (राइनो) प्राप्त कर सकते हैं और लगभग सभी को कुछ जावास्क्रिप्ट जानने की आवश्यकता है।
माइकल डिलन

ये मूल्य कहाँ से आते हैं? यह एक bashचर में डालकर एक अतिरिक्त कदम जोड़ने की तुलना में मूल स्रोत से अक्षांश और देशांतर मानों को पार्स करने के लिए अधिक कुशल होगा ।
Kusalananda

जवाबों:


18

इसे शुद्ध शेल सिंटैक्स के माध्यम से हल किया जा सकता है। कोष्ठक (कोष्ठक) के कारण इसे एक अस्थायी चर की आवश्यकता होती है:

#!/bin/bash

LATLNG="(53.3096,-6.28396)"

tmp=${LATLNG//[()]/}
LAT=${tmp%,*}
LNG=${tmp#*,}

वैकल्पिक रूप से, आप इसे बिलिन के साथ खेलने IFSऔर उपयोग करके एक बार में कर सकते हैं read:

#!/bin/bash

LATLNG="(53.3096,-6.28396)"

IFS='( ,)' read _ LAT LNG _ <<<"$LATLNG"

पहला उदाहरण केवल bash में काम करेगा, POSIX शेल में नहीं।
जेलरैन

1
@ हेग्रेलेन इसलिए#!/bin/bash
सेजएक्स

यहाँ और विस्तार देखें: gnu.org/software/bash/manual/…
रिकार्डो स्टू

22

इस विशेष मामले के लिए सीजएक्सएक्स का जवाब बेहतर है, लेकिन आपको यह भी पता होना चाहिए कि कैसे मनमाना पाठ पास करना है sed

sedअपने दूसरे, तीसरे, आदि मापदंडों के रूप में फ़ाइल नाम की अपेक्षा कर रहा है, और यदि इसे कोई फ़ाइल नाम नहीं मिलता है, तो यह अपने मानक इनपुट से पढ़ता है। इसलिए यदि आपके पास वह पाठ है जिसे आप संसाधित करना चाहते हैं जो किसी फ़ाइल में नहीं है, तो आपको इसे पाइप करना होगा sed। सबसे सीधा तरीका यह है:

echo "blah blah" | sed 's/blah/blam/g'

तो आपका उदाहरण बन जाएगा:

LAT=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\1/g')
LON=$(echo "$LATLNG" | sed 's/(\(.*\),\(.*\))/\2/g')

वैकल्पिक (बेहतर लेकिन अधिक अस्पष्ट) तरीके

यदि आपको लगता है कि ऐसा कोई मौका है जो $LATLNGडैश के साथ शुरू हो सकता है, या यदि आप पांडित्यपूर्ण होना चाहते हैं, तो आपको printfइसके बजाय उपयोग करना चाहिए echo:

printf '%s' "$LATLNG" | sed 's/foo/bar/g'

या एक "यहाँ दस्तावेज़", लेकिन उस निर्माण के साथ थोड़ा अजीब हो सकता है जिसका आप उपयोग कर रहे हैं:

LAT=$(sed 's/foo/bar/g' <<END
$LATLNG
END
)

या यदि आप bashपोर्टेबिलिटी के बारे में चिंतित और चिंतित नहीं हैं, तो आप "यहां स्ट्रिंग" का उपयोग कर सकते हैं:

sed 's/foo/bar/g' <<< "$LATLNG"

3

यहाँ एक समाधान है जो किसी भी POSIX शेल में काम करेगा:

parse_coordinates () {
  IFS='(), '  # Use these characters as word separators
  set -f      # Disable globbing
  set $1      # Split $1 into separate words
  set +f      # Restore shell state
  unset IFS
  LAT=$2      # $1 is the empty word before the open parenthesis
  LON=$3
}
parse_coordinates "$LATLNG"

यहां एक और समान रूप से पोर्टेबल समाधान है जो उपयोग किए गए विशिष्ट सिंटैक्स को पार्स करता है।

LAT=${LATLNG%\)}    # strip final parenthesis
LAT=${LAT#\(}       # strip initial parenthesis
LON=${LAT##*[, ]}   # set LON to everything after the last comma or space
LAT=${LAT%%[, ]*}   # set LAT to everything before the first comma or space

-1
LATLNG="(53.3096,-6.28396)"
set ${LATLNG//[(,)]/ }
LAT=$1
LON=$2

आपको शायद करना चाहिए set -- ...पहला चरित्र एक बहुत अच्छा मौका है -
मिकसर्व
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.