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[@]}"