for name in *.txt; do
cut -f 5,10 -- "$name" | sort -k 1,1 >"$name.sort"
done
This would combine the effect of the two initial loops while getting rid of the use of the intermediate files.
I did some small modifications:
- Quoting of the expansion of all variables, because When is double-quoting necessary?
- Using a better name for the loop variable.
- Delimiting the variable from the
cut
command using --
to signal the end of options, in case the filename in $name
starts with a dash.
One could also have used sort -k 1,1 -o "$name.sort"
in place of the sort
command above, to let the sort
utility create the output file rather than the shell (minor difference).
The xargs
utility is often used instead of a loop:
printf '%s\n' *.txt | xargs -I {} sh -c 'cut -f 5,10 -- "$1" | sort -k 1,1 >"$1.sort"' sh "{}"
... but here it just makes thing more complicated (the command above would have issues handling filename containing newlines).
Your command
cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1 {} >$i.sort
would do the cut
and save the output to $i.txt.out
(with $i
expanded). The xargs
command would get no input due to the output of cut
being redirected to a file. If you hadn't redirected the output of cut
, xargs
would have executed sort
with the contents of the files as arguments rather than with the filenames. This is not what you want (you want to pass the output of cut
as data into sort
).