How to use bash substitution to add a new line at the end of each list item

I'm looking for bash one liner that adds a new line after each list item. If I call the script like:

./script arg1 arg2 arg3 

I want the output to be

 arg1 arg2 arg3 

I tried different options for the following. A new line is not added. Any regular char is added.

 # pretty much works except for an extra space list=${@/%/x} echo "$list" # appends 'n' list=${@/%/\n} echo "$list" # appends nothing list=${@/%/$'\n'} echo "$list" # appends nothing, \x078 would append 'x' list=${@/%/$'\x0D'} echo "$list" # appends nothing CR=$'\n' list=${@/%/$CR} echo "$list" # same issues with arrays tmp=( $@ ) list=${tmp/%/\n} echo "$list" 

What fix or alternative do you suggest? I obviously could write a loop or call tr, but exactly what I thought I managed to avoid when replacing bash.

+5
source share
2 answers

You can use this function with " $@ " :

 f() { printf "%s\n" " $@ "; } f arg1 arg2 arg3 arg1 arg2 arg3 

According to man bash

  @ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, " $@ " is equivalent to "$1" "$2" ... 
+5
source

printf would be my answer too. Another way is to use IFS :

 $ IFS=$'\n' $ list="$*" $ echo "$list" arg1 arg2 arg3 

Notes:

  • uses ANSI-C for newline
  • "$*" ( with quotes , is critical) combines positional parameters using the first char of $ IFS
  • specify the shell variable for the echo command to save the internal lines.

This overrides the IFS value for the current shell. You can first save the old value and restore it after:

 oldIFS=$IFS; IFS=$'\n'; list="$*"; IFS=$oldIFS 

or you can use a subshell so that the changes are discarded for you:

 $ list=$( IFS=$'\n'; echo "$*" ) 
+2
source

Source: https://habr.com/ru/post/1208595/


All Articles