print a defined variable with preserving $ - shell

I would like to print 120 model list along with preserving the "$".
My script is:
#!/bin/sh
for i in {1..10};do
declare model="$"model$i
model_list=$(paste $model)
done
echo $model_list
After running it,
paste: $model1: No such file or directory
paste: $model2: No such file or directory
paste: $model3: No such file or directory
paste: $model4: No such file or directory
paste: $model5: No such file or directory
paste: $model6: No such file or directory
paste: $model7: No such file or directory
paste: $model8: No such file or directory
paste: $model9: No such file or directory
paste: $model10: No such file or directory
Desired output:
$model1 $model2 $model3 $model4 $model5 $model6 $model7 $model8 $model9 $model10

if you are interested in output instead of creating array the you can use below code
for i in {1..10};do
echo -n "\$model$i "
done
echo
or
for i in {1..10};do
echo -n '$model'$i' '
done
echo
or
for i in {1..10};do
model_list=$model_list" \$model$i"
done
echo $model_list

You have to escape the $ via \$ (backslash dollar-sign).
For instance:
#!/bin/sh
for i in {1..10}; do
declare model="\$"model$i
model_list+=$(paste $model)
done
echo $model_list
You can also shorten your script:
#!/bin/sh
for i in {1..10}; do
model_list+=$(paste "\$model${i}")
done
echo $model_list
Tested with 5 files titled $model1 - $model5:
File Contents:
$model1 - a b c d e f g
$model2 - 1 2 3 4 5 6 7 8 9 10
$model3 - I J K L M N O P
$model4 - 11 12 13 14 15 16 17 18 19 20
$model5 - q r s t u v w x y z
Output:
a b c d e f g1 2 3 4 5 6 7 8 9 10I J K L M N O P11 12 13 14 15 16 17 18 19 20q r s t u v w x y z

Related

How to append a character at the end of a specific line in a loop?

I want to read line numbers from a file and according to that insert characters in another file. This is what I got so far:
#!/bin/bash
character=:
line_number=1
sed $line_number's/$/ '$character'/' <readme >readme_new
line_number=3
sed $line_number's/$/ '$character'/' <readme_new >readme_newer
I would like to do that in a loop now.
TL;DR:
$: c='!'
$: sed "s#\$# s/\$/ $c/#" fibs >script
$: sed -i "$(<script)" infile
Broken out -
A file of line numbers:
$: cat fibs
1
2
3
5
8
13
21
a file to be edited:
$: cat infile
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
11 k
12 l
13 m
14 n
15 o
16 p
17 q
18 r
19 s
20 t
21 u
22 v
23 q
24 x
25 y
26 z
3 steps -- first set your character variable if you're using one.
$: c='!'
Then make a script from the line number file -
$: sed "s#\$# s/\$/ $c/#" fibs >script
which creates:
$: cat script
1 s/$/ !/
2 s/$/ !/
3 s/$/ !/
5 s/$/ !/
8 s/$/ !/
13 s/$/ !/
21 s/$/ !/
It's a simple sed to add a sed substitution command for each line number, and sends the resulting script to a file. A few tricks here include using double-quotes to allow the character embedding, and #'s to allow the replacement text to include /'s without creating leaning-toothpick syndrome from all the backslash quoting.
Then run it against your input -
$: sed -i "$(<script)" infile
Which does the work. That pulls the script file contents in for sed to use, generating:
1 a !
2 b !
3 c !
4 d
5 e !
6 f
7 g
8 h !
9 i
10 j
11 k
12 l
13 m !
14 n
15 o
16 p
17 q
18 r
19 s
20 t
21 u !
22 v
23 q
24 x
25 y
26 z
Let me know if you want to tweak it.

Bash_shell Use shell to convert three format in one script to another script at one time

cat file1.txt
set A B 1
set C D E 2
set E F 3 3 3 3 3 3
cat file2.txt
A;B;1;
C;D.E;2;
E;F;3 3 3 3 3 3;
please help convert the format in file1.txt to file2.txt, the file2.txt is the output. I just input 3 lines in file1.txt for taking example, but in fact ,there are many command lines same with these 3 format.So the shell command should be adapt to any situation where the content contains these 3 format in file1.txt.
echo "set A B 1
set C D E 2
set E F 3 3 3 3 3 3 " | sed -r 's/set (.) /\1;/;s/([A-Z])*( ([A-Z]))/\1.\3/g;s/([A-Z]) ([0-9])/\1;\2/;s/ ?$/;/'
A;B;1;
C;D.E;2;
E;F;3 3 3 3 3 3;

Print variable inside awk while calculating variable name

I have a script that looks like the example below. I have a letter offset and I need to print the letter that I calculate with the offset. I am not sure how to read that letter using ksh.
My expected answer would be for LETTER_OFFSET(1)=a,LETTER_OFFSET(2)=v, LETTER_OFFSET(3)=c, etc. The offset I have it been calculated inside a loop.
#!/bin/ksh
# 1 2 3 4 5 6 7 8 9 10 11 12
LETTERS=" a v c d g r g s s a g f"
LETTER_OFFSET="3";
Letter=$(echo $LETTERS | awk '{print $((1 * $$LETTER_OFFSET )) }')
You'll pass your offset into your awk script to use as an awk variable using the awk -v flag:
LETTER=$(echo $LETTERS | awk -v offset=$LETTER_OFFSET '{print $offset}')
You don't need to invoke awk in every iteration. You can populate an array using your letters and then access it's values using index:
#!/bin/ksh
# 1 2 3 4 5 6 7 8 9 10 11 12
letters=" a v c d g r g s s a g f"
# populate an array
arr=($letters)
offset=1
while [ "$offset" -le 12 ]; do
echo "${arr[$offset-1]}"
let offset++
done
Output:
a
v
c
d
g
r
g
s
s
a
g
f

Nested for loop - output once

I have a nested for loop to print one letter each from each variable.
for i in a b ; do for j in 1 2; do echo "$i $j"; done; done
a 1
a 2
b 1
b 2
My requirement is to have as
a 1
b 2
How do I get it ?
letters=(a b c d) # declare an array with four elements
numbers=(1 2 3 4)
for ((i=0;i<${#letters[#]};i++)); do echo ${letters[$i]} ${numbers[$i]}; done
Output:
a 1
b 2
c 3
d 4
${#letters[#]} is the number of elements in array letters.
You can also do the same using regular variables and string indexes:
#!/bin/bash
letters="abcdefghi"
nums="123456789"
for ((i = 0; i < ${#nums}; i++)); do
printf "%s %s\n" ${letters:i:1} ${nums:i:1}
done
Output
$ bash prnidx.sh
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9

Unix Command (Mac OS): cut and move rows

Could you please give me a hint which unix command I can use to do the following:
I want to convert these lines...
1 a i
2 b ii
3 c iii
4 d iv
5 e v
6 f vi
7 g vii
8 h viii
9 i xi
...into those:
1 a i 4 d iv 7 g vii
2 b ii 5 e v 8 h viii
3 c iii 6 f vi 9 i xi
rsand perl -pne just transpose them but I need a completely new arrangement as you see. Perl-code would be favored, but I am thankful for any help.
cheers
marsch
Using a perl one-liner
perl -lne 'push #{$l[($.-1) % 3]}, $_; }{ print "#$_" for #l' data.txt | column -t
Explanation:
Switches:
-l: Enable line ending processing, specifies line terminator
-n: Creates a while(<>){..} loop for each line in your input file.
-e: Tells perl to execute the code on command line.
Code:
push #{$l[($.-1) % 3]}, $_;: Push each line into an array modulo the line number
}{ print "#$_" for #l: Print the 3 element array at end of processing
| column -t: Even out the columns
I would go with split and paste from coreutils. Try the following commands:
split -l3 infile
paste -d' ' xaa xab xac | column -t
Output:
1 a i 4 d iv 7 g vii
2 b ii 5 e v 8 h viii
3 c iii 6 f vi 9 i xi
Here is a oneliner:
perl -ne 'chomp; push #a,$_ if $_; unless($. % 3) {push #f,[#a]; #a = undef; shift #a} END {for my $i (#f) { for (#$i) {print "$_ "} print "\n"}}' filename.txt
output
1 a i 2 b ii 3 c iii
4 d iv 5 e v 6 f vi
7 g vii 8 h viii 9 i xi
I use ruby
string = "1 a i
2 b ii
3 c iii
4 d iv
5 e v
6 f vi
7 g vii
8 h viii
9 i xi "
ary = string.split("\n")
length = ary.size / 3
new_ary = Array.new(3, "")
ary.each_with_index do |e, i|
position = i % 3
new_ary[position] += e
end
puts new_ary.join("\n")
Hope to help:)

Resources