Reputation: 8605
I am new to bash shell scripting and would be thankful for suggestions of a script that can do this task. I have a file (list.cqt) with many lines. Each line has a list of fields separated by '/' in the following format: /Field1/Field2/Field3/Field4/Field5/Field6/Field7/Field8/Field9/Field10
For e.g. the contents in list.cqt are:
/F11/F12/F13/F14/F15/F16/F17/F18/F19/F110
/F21/F22/F23/F24/F25/F26/F27/F28/F29/F210
...
/Fx1/Fx2/Fx3/Fx4/Fx5/Fx6/Fx7/Fx8/Fx9/Fx10
(I modifyied the names inside each field just for simplifying the problem. Only the number of fields is constant in each line. Contents in each field can be anything - numbers, characters, etc)
I need to write a script to execute the following command by reading each line from list.cqt:
command arg1 arg2 arg3 arg4 *arg5* arg6 arg7 arg8 arg9 arg10
Only arg4, arg5, arg7 and arg10 change for each line read. Rest all remain the same.
arg4 is Field4 in that line in list.cqt
arg5 is Field6 in that line in list.cqt
arg7 basically starts with -1000 for the first command and changes in increments of 100. So for the second command it will be -900 for second command, so on, and 0 for 11th command, 100 for 12th command, 200 for 13th command etc.
arg10 is same absolute value as arg7 but with opposite sign. So if arg7 is -600, arg10 is 600. If arg7 is 400, arg10 is -400.
For example, reading the first two lines from list.cqt in the above example of the file, the commands will be:
command arg1 arg2 arg3 F14 F16 arg6 -1000 arg8 arg9 1000
command arg1 arg2 arg3 F24 F26 arg6 -900 arg8 arg9 900
Thank you!
Upvotes: 1
Views: 3212
Reputation: 64573
I added echo
before command because it's better to check if generated list is correct:
arg7=-1000
arg10=1000
while read line
do
set $(echo $line | tr / ' ')
echo command arg1 arg2 arg3 "$4" "$6" arg6 "$arg7" arg8 arg9 "$arg10"
arg10=$((arg10-100))
arg7=$((arg7+100))
done < list.cqt
If it is, just remove echo
and run the script.
Here you process list.cqt
line by line and set parts of its line to positional arguments of shell; then you use this parts as $4
and $6
. Variables arg10
and arg7
are increased/decreased each time a line from the list.cqt
file is processed.
Update
You can also use arrays instead of positional arguments (thanks to Dennis Williamson and kojiro for the tip):
arg7=-1000
arg10=1000
while IFS=/ read line
do
echo command arg1 arg2 arg3 "${line[4]}" "${line[6]}" arg6 "$arg7" arg8 arg9 "$arg10"
arg10=$((arg10-100))
arg7=$((arg7+100))
done < list.cqt
That makes the code a little bit faster and cleaner.
Upvotes: 2
Reputation: 77137
You can control the delimiter of the shell's read
command via the Internal Field Separator IFS
. If you read into an array it's easy to access the indexed values. Then it becomes a simple matter of looping over the input and updating your counter variables. If you save the arguments to an array, you can just pass the expanded array as the arguments to your command.
#!/bin/bash
# Use set -x to see if the array "args" is getting assigned the values you expect.
IFS='/'
counter=-1000
while read -a fields; do
(( counter+=100 ))
args=(
'arg1' 'arg2' 'arg3'
"${fields[4]}" "${fields[6]}" 'arg6'
$counter 'arg8' 'arg9' $(( -1 * counter ))
)
# command "${args[@]}"
done < list.cqt
Upvotes: 3