0

I would like to print content of directory separated by specific delimiter (in my case ':'). So I am searching for equivalent of this loop:

for f in * ; do printf $f: ; done

But this loop print extra ':' at the end and I am pretty sure there is more elegant solution for my case. I tried something like

echo * | tr " " :

But there is a problem if filename contains spaces. Any ideas?

oguz ismail
  • 1
  • 16
  • 47
  • 69
kosciej16
  • 6,294
  • 1
  • 18
  • 29

3 Answers3

3

When wrapped in double quotes, $* expands to a list of positional parameters separated with the first character of IFS. So, here you go:

( set -- * ; IFS=':' ; printf '%s\n' "$*" )
oguz ismail
  • 1
  • 16
  • 47
  • 69
  • Nice! U could replace `printf '%s\n'` by simply `echo`. – F. Hauri - Give Up GitHub Dec 07 '19 at 13:42
  • @F.Hauri Nah, echo is not reliable. See [Why is printf better than echo?](//unix.stackexchange.com/q/65803) – oguz ismail Dec 07 '19 at 13:45
  • ?? `(set -- *;IFS=:;echo "$*")` work fine and to set a variable: `dirColon=$(set -- *;IFS=:;echo "$*")`! What do you mean by *not reliable*? (Note: quotes on colons in `IFS=` declaration are useless) – F. Hauri - Give Up GitHub Dec 07 '19 at 13:48
  • 1
    Follow the link I added to my comment. I really don't have time for giving a lecture about it. And quotes in variable assignment is a matter of taste; I like it that way – oguz ismail Dec 07 '19 at 13:50
  • Its great command oguz, but two things are not clear for me: 1) Why double dash in set? I know what is general meaning of double dash, but can't find example why could I need it here. 2) Couldn't the last part be just printf "$*"? Do we need the string format part? – kosciej16 Dec 07 '19 at 16:59
  • @oguzismail I just noticed it doesn't solve my problem - I wanted to set PYTHONPATH via this command, but when I write export PYTHONPATH=$(your command) it has no colons ;/ – kosciej16 Dec 07 '19 at 17:09
  • @user3361462 `export PYTHONPATH=$(set -- *;IFS=':';printf '%s\n' "$*")` works fine here. Wrt *why double dash?*; to tell `set` no further options are given on the command line. And *do we need the format part?* yes, otherwise a filename containing `%` would break it. – oguz ismail Dec 07 '19 at 17:47
1
for f in * ; do printf $f: ; done | sed 's/.$//'

Will do the trick

Also here is another option: How can I join elements of an array in Bash?

Strelok
  • 50,229
  • 9
  • 102
  • 115
0

You can remove the trailing : with sed:

for f in * ; do printf $f: ; done | sed 's/:$//'

But the printf %f will fail if filename has for example %s or %d or %f or %c or space or tab in the filename. It's better to quote your variables and do:

for f in * ; do printf "%s:" "$f"; done | sed 's/:$//'

Or just:

printf "%s:" * | sed 's/:$//'

If filenames do not have newlines, you could print them with newlines and join using paste:

printf "%s\n" * | paste -sd:

Or you could use IFS with $* expansion to join the output, with additional function:

f() { ( IFS=:; printf "%s" "$*"; ); }; f *
KamilCuk
  • 120,984
  • 8
  • 59
  • 111