The typical usage for xargs is feeding it multiple lines of input, and having it run commands using each line as an argument.
But there are other cases when you have a single line separated by a delimiter or even a list of optionally quoted args, and I’ll show in this article how to handle those as well.
The most basic case is using xargs on multiple lines of input. This is the basic case of taking each line and bookending it with BEGIN and END strings.
$ cat <<EOF > sep-by-lines.txt > a > b > c > one hundred > two hundred > EOF $ cat sep-by-lines.txt | xargs -I {} echo BEGIN {} END BEGIN a END BEGIN b END BEGIN c END BEGIN one hundred END BEGIN two hundred END
The next case is where you have a list of items, but this time they are all on a single line separated by a marker such as a comma. You can set the delimiter with “-d”.
$ echo -n "a,b,c,one hundred,two hundred" > sep-by-commas.txt $ cat sep-by-commas.txt | xargs -d ',' -I {} echo BEGIN {} END BEGIN a END BEGIN b END BEGIN c END BEGIN one hundred END BEGIN two hundred END
But a much harder case is where you have a list of items all on a single line, but they are optionally quoted. In this case it is not enough to set IFS, you need to parse with an awk pattern:
$ echo 'a b c "one hundred" "two hundred"' > quoted-params.txt $ cat quoted-params.txt | awk 'BEGIN{FPAT = "([^[:space:]]+)|(\"[^\"]+\")"}{for(i=1;i<=NF;i++) print $i}' | xargs -I {} echo BEGIN {} END BEGIN a END BEGIN b END BEGIN c END BEGIN one hundred END BEGIN two hundred END
REFERENCES
stackoverflow, FPAT solution by Inian
NOTES
simple xargs on files directly in folder
find . -maxdepth 1 -type f -name \*.txt | xargs -I {} echo BEGIN {} END
Find and xargs pair if there might be special chars
find . -maxdepth 1 -type f -name \*.txt -print0 | xargs --null -I {} echo BEGINTEXT {} ENDTEXT
Easier way to do single line with arguments separated by a delimiter
$ IFS=','; for i in $(cat sep-by-commas.txt); do echo BEGIN $i END; done
direct multiline heredoc sent to xargs to be processed line by line
$ xargs -I {} echo BEGIN {} END << EOF a b c one hundred two hundred EOF