Home > Software engineering >  How to use comma separated paths with whitespace as arguments in Bash?
How to use comma separated paths with whitespace as arguments in Bash?

Time:03-11

I have a dynamic list of paths, each of which may or may not contain whitespace within itself. For example,

$ STRING='./my text1.txt,./my text2.txt'

My ultimate goal is to input those paths as arguments of a command, say cat:

$ cat "./my text1.txt" "./my text2.txt"
cat: ./my text1.txt: No such file or directory  # this is expected!
cat: ./my text2.txt: No such file or directory

So I tried:

$ STRING='./my text1.txt,./my text2.txt'
$ SEP="\"${STRING//,/\" \"}\""
$ echo $SEP
"my text1.txt" "my text2.txt"
$ cat $SEP                          
cat: "my text1.txt" "my text2.txt": No such file or directory

In the example above, note that "my text1.txt" "my text2.txt" is recognized as a single argument.

My question is, given STRING, what do I need to make cat recognize SEP as two separate arguments?

Thanks.


Context

To give you more information on the context, I'm trying to write a script for Github Actions to integrate SwiftFormat and changed-files.

- name: Get list changed files
  id: changed-files
  uses: tj-actions/changed-files@v17
  with:
    files: |
      **/*.swift

- name: Format Swift code
  run: swiftformat --verbose ${{ steps.changed-files.outputs.all_changed_files }} --config .swiftformat

So I assumed that STRING is given and that manually escaping whitespaces (e.g ./my\ text1.txt) is not an option for me.

CodePudding user response:

Assuming that your filenames don't have space/glob characters you can use:

str='./my text1.txt,./my text2.txt'
printf '%s\n' "${str//,/ }" | xargs cat

In case your file names can contain whitespaces then use any of these 2 solutions:

(IFS=, read -ra arr <<< "$str"; cat "${arr[@]}")

awk -v ORS='\0' '{gsub(/,/, ORS)} 1' <<< "$str" | xargs -0 cat

CodePudding user response:

You have to split the string on , into an array.

string='./my text1.txt,./my text2.txt'
IFS=, read -r -a files  <<<"$string"
cat "${files[@]}"

or

readarray -t -d '' files < <(tr ',' '\0' <<<"$string")
cat "${files[@]}"
  • Related