कैसे मैं एक बैश सरणी चर को एक नई सीमा के साथ सीमांकित स्ट्रिंग में परिवर्तित करूं?


50

मैं एक फ़ाइल के लिए बैश एरे चर को एक नई लाइन पर प्रत्येक तत्व के साथ लिखना चाहता हूं। मैं लूप के लिए ऐसा कर सकता हूं, लेकिन क्या तत्वों के साथ जुड़ने का एक और (क्लीनर) तरीका है \n?

जवाबों:


59

यहां एक तरीका है जो बैश पैरामीटर विस्तार और इसके IFSविशेष चर का उपयोग करता है ।

$ System=('s1' 's2' 's3' 's4 4 4')
$ ( IFS=$'\n'; echo "${System[*]}" )

हम IFSवर्तमान वातावरण में मूल्य को अधिलेखित करने से बचने के लिए एक उपधारा का उपयोग करते हैं। उस उपधारा में, हम तब मूल्य को संशोधित करते हैं IFSताकि पहला वर्ण एक नई पंक्ति ( $'...'उद्धरण का उपयोग करके ) हो। अंत में, हम एक शब्द के रूप में सरणी की सामग्री को प्रिंट करने के लिए पैरामीटर विस्तार का उपयोग करते हैं; प्रत्येक तत्व पहले चारित्र द्वारा अलग किया जाता है IFS

एक चर पर कब्जा करने के लिए:

$ var=$( IFS=$'\n'; echo "${System[*]}" )

यदि आपका बैश काफी नया है (4.2 या बाद में), तो आप विकल्प के printfसाथ अभी भी उपयोग कर सकते हैं (और चाहिए) -v:

$ printf -v var "%s\n" "${System[@]}"

किसी भी स्थिति में, आप अंतिम नई पंक्ति नहीं चाह सकते हैं var। इसे हटाने के लिए:

$ var=${var%?}    # Remove the final character of var

धन्यवाद, वहाँ एक चर के लिए यह उत्पादन करने के लिए एक रास्ता है?
एसीसाइकल

एक चर पर कब्जा करने के तरीके को दिखाने के लिए अद्यतन किया गया।
chepner

2
var=${var%?}इसके बजाय अंतिम उदाहरण नहीं होना चाहिए ? यह एक नियमित अभिव्यक्ति नहीं है, इसलिए .केवल एक अवधि चरित्र से मेल खाएगा।
मुशीफिल

सरणी चर नाम का उद्धरण आवश्यक है:$ IFS=', ' $ echo ${VAR[*]} first second third $ echo "${VAR[*]}" first,second,third
Seff

28

आप printfप्रत्येक सरणी आइटम को अपनी लाइन पर प्रिंट करने के लिए उपयोग कर सकते हैं :

 $ System=('s1' 's2' 's3' 's4 4 4')
 $ printf "%s\n"  "${System[@]}"
s1
s2
s3
s4 4 4

7
awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"

या

perl -le 'print join "\n",@ARGV' "${arr[@]}"

या

python -c 'import sys;print "\n".join(sys.argv[1:])' "${arr[@]}"

या

sh -c 'IFS=$'\''\n'\'';echo "$*"' '' "${arr[@]}"

या

lua <(echo 'print(table.concat(arg,"\n"))') "${arr[@]}"

या

tclsh <(echo 'puts [join $argv "\n"]') "${arr[@]}"

या

php -r 'echo implode("\n",array_slice($argv,1));' -- "${arr[@]}"

या

ruby -e 'puts ARGV.join("\n")' "${arr[@]}"

यह सब मैं अब तक याद दिला सकता हूं।


2

उपरोक्त समाधान बहुत अधिक हैं, लेकिन मूल प्रश्न फ़ाइल में आउटपुट के लिए पूछता है:

$ a=(a b c d e)
$ ( IFS=$'\n'; echo "${a[*]}" ) > /tmp/file
$ cat /tmp/file
a
b
c
d
e
$

नोट: 1) 'इको' अंतिम न्यूलाइन 2 प्रदान करता है) यदि यह फाइल बस बैश द्वारा फिर से पढ़ी जाएगी, तो घोषणा -p क्रमबद्धता चाहता था हो सकता है।


2

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

for each in "${alpha[@]}"
do
  echo "$each"
done

इतिहास का उपयोग करना ; ध्यान दें कि यह विफल हो जाएगा यदि आपके मान शामिल हैं !:

history -p "${alpha[@]}"

बेसन का उपयोग करना ; ध्यान दें कि यह विफल हो जाएगा यदि आपके मान शामिल हैं /:

basename -a "${alpha[@]}"

शूफ का उपयोग करना ; ध्यान दें कि परिणाम क्रम में नहीं आ सकते हैं:

shuf -e "${alpha[@]}"

0

मेरी , केवल बग बैश का उपयोग करते हुए, बिना उत्परिवर्तन के IFS:

# $1  separator
# $2… strings
join_strings () {
    declare separator="$1";
    declare -a args=("${@:2}");
    declare result;
    printf -v result '%s' "${args[@]/#/$separator}";
    printf '%s' "${result:${#separator}}"
}

उदाहरण

$ join_strings $'\n' "a b c" "d e f" "g h i"
a b c
d e f
g h i

आप किसी भी विभाजक का उपयोग कर सकते हैं:

$ join_strings '===' "a b c" "d e f" "g h i"
a b c===d e f===g h i

-1

printf एक सरणी से एक सीमांकित स्ट्रिंग बनाने के लिए सबसे कुशल दृष्टिकोण प्रतीत होता है:

# create a delimited string; note that printf doesn't put the trailing delimiter
# need to save and restore IFS
# it is prudent to put the whole logic on a single line so as to minimize the risk of future code changes breaking the sequence of saving/restoring of IFS
oldIFS=$IFS; IFS=$'\n'; printf -v var "${arr[*]}"; IFS=$oldIFS

# print string to file; note that the newline is required in the format string because printf wouldn't put a trailing delimiter (which is a good thing)
printf '%s\n' "$var" > file

ऐसा करने का एक सरल तरीका यह भी है:

delim=$'\n'
printf -v var "%s$delim" "${arr[@]}" # create a delimited string
var="${var%$delim}"                  # remove the trailing delimiter

उदाहरण

delim=:
arr=(one two three)
printf -v var "%s$delim" "${arr[@]}" # yields one:two:three:
var="${var%$delim}"                  # yields one:two_three

2
डाउनर, कृपया टिप्पणी करें कि यहां क्या गलत है।
कोडवर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.