$ perl -le 'print join ",", map { "Pkg" . ++$i . "=$_" } @ARGV' perl runtime pool tools
Pkg1=perl,Pkg2=runtime,Pkg3=pool,Pkg4=tools
map { "Pkg" . ++$i . "=$_" } @ARGV
returns a list where each element is one of the command-line arguments prefixed by the literal string Pkg
, a counter variable ($i
), which is auto-incremented on each pass through the map
loop, and a literal =
symbol. See perldoc -f map
for details on how it works.
The list is joined with commas as separators and then printed. See perldoc -f join
.
The -l
option enables automatic line-ending processing. For this script, since there is no stdin to process, all that means is that a newline is automatically output with each print
statement (normally, perl's print
does not output a newline unless you explicitly include it). See man perlrun
and search for -l\[octnum\]
.
If you want to accept user input first (which, as others have pointed out, is not recommended because it's hugely annoying and inconvenient to users), then you could do it with something like:
#!/bin/bash
# read the user input into array variable "$input"
read -p "Specify the package: " -r -a input
# now pass the array to the perl one-liner
perl -le 'print join ",", map { "Pkg" . ++$i . "=$_" } @ARGV' -- "${input[@]}"
The --
prevents perl from interpreting any of of the user input as options, just in case the user accidentally (or maliciously) enters something like a perl command-line option - e.g. -e ';system("rm -rf /");'
. Never trust user-supplied input.
and, as usual, if you need to capture the output of the perl script into another shell variable, use command substitution:
var=$(perl -le 'print join ",", map { "Pkg" . ++$i . "=$_" } @ARGV' -- "${input[@]}")
printf "%s\n" "$var"