विभिन्न चर के लिए एक फ़ाइल की विभिन्न लाइनों को पढ़ने के लिए कैसे?


14

मैं एक पाठ फ़ाइल की विभिन्न लाइनों को अलग-अलग चर में पढ़ना चाहूंगा। उदाहरण के लिए

input.txt:

line1 foo foobar bar
line2 bar
line3 foo
line4 foobar bar

मैं चाहता हूँ इस परिणाम चर में संग्रहीत करने के लिए var1, var2, var3और var4ऐसा है कि

var1=line1 foo foobar bar
var2=line2 bar

और इसी तरह।

क्या कोई मुझे बता सकता है कि यह कैसे किया जाता है। मैंने evalलूप के लिए उपयोग करने की कोशिश की । यह काम नहीं लगता है।



3
यह एक बुरा तरीका है। मूल रूप से सेट चर के लिए एक ही कारण है के बाद से उनके साथ कुछ करते हैं, और के बाद से वहाँ उपकरण विशेष रूप से बहुत बड़ी संख्या में हैं के लिए बनाया गया एक फ़ाइल में पाठ के हर लाइन के साथ काम करने के लिए (Awk, Sed, grep, cut, एट। अल।), यह बहुत बेहतर है कि सिर्फ वही करें जो आपको करने की आवश्यकता है। एक खोल स्क्रिप्ट में micromanage मत करो; काम पाने के लिए ऑर्केस्ट्रेट टूल।
वाइल्डकार्ड

जवाबों:


20

आप ऐसा करेंगे:

unset -v line1 line2
{ IFS= read -r line1 && IFS= read -r line2; } < input.txt

या:

{ line1=$(line) && line2=$(line); } < input.txt

(कम कुशल के रूप lineमें शायद ही कभी बनाया गया है और अधिकांश गोले को कमांड प्रतिस्थापन को लागू करने के लिए कांटा की आवश्यकता होती है। lineयह अब एक मानक कमांड नहीं है)।

एक लूप का उपयोग करने के लिए:

unset -v line1 line2 line3
for var in line1 line2 line3; do
  IFS= read -r "$var" || break
done < input.txt

या चर के नाम को स्वचालित रूप से परिभाषित करने के लिए line<++n>:

n=1; while IFS= read -r "line$n"; do
  n=$((n + 1))
done < input.txt

bashसरणी readarrayमें लाइनों को पढ़ने के लिए सरणी चर और एक बेसिन का समर्थन करने वाले नोट :

readarray -t line < input.txt

नोट अधिकांश अन्य गोले के विपरीत, तथापि कि bashसरणी सूचकांक 0 नहीं 1 (से विरासत में मिली पर शुरू ksh), तो पहली पंक्ति में होगा ${line[0]}, नहीं ${line[1]}(हालांकि के रूप में @Costas से पता चला है , तो आप कर सकते हैं readarray(उर्फ mapfile) indice पर मूल्यों लेखन शुरू 1 ( basharrays भी ज्यादातर अन्य गोले ' विरल सरणियों के साथ विपरीत ) के साथ -O 1)।

इसे भी देखें: "IFS = read -r line" को समझें?


12

मैं इस तरह के कार्य के लिए सरणी का उपयोग करने की पेशकश करूंगा

mapfile -t -O 1 var <input.txt

ताकि आप में प्रत्येक पंक्ति होगा ${var[1]}, ${var[2]}और इतने पर


यह वन-लाइनर बहुत अच्छा काम करता है। मेरे लिए समस्या का समाधान किया।
मैट ज़ाबोजनिक

0

यह कड़ाई से नहीं है कि आपने क्या मांगा है, लेकिन यह आपकी आवश्यकताओं के लिए काम कर सकता है। आप Awk के साथ डेटा को क्रमबद्ध कर सकते हैं। ध्यान दें कि यह टूट जाएगा यदि आपका $ 1 एक वैध चर नाम नहीं है:

awk '
function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] (y < m ? d "\\" d : d)
  return z
}
{
  print $1 "=" quote($0)
}
' input.txt > /tmp/input.sh
. /tmp/input.sh

परिणाम:

$ echo "$line1"
line1 foo foobar bar

यह गंभीर रूप से अजीब कोड है! ऐसा प्रतीत होता है कि आप पूरी इनपुट फ़ाइल को bash स्क्रिप्ट में बदलने के लिए awk का उपयोग कर रहे हैं, जिसे आप तब स्रोत करते हैं। मुझे एक अस्पष्ट विचार है कि क्या उद्धरण () कर रहा है। अधिक वर्णनात्मक चर नाम मदद करेंगे। क्या आप चीजों को थोड़ा और समझा सकते हैं?
जो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.