1

I have two for loops below which creates final output as the sorted file,but I want to merge into one for loop only

for i in *.txt; do
    cut -f 5,10 $i >$i.txt.out
done

###sorting

for i in *.txt.out; do
    sort -k1,1 $i >$i.sort
done

I tried merging the two loops into one by redirecting the output from the first for loop using pipe. I tried one of the method from this post (Pass the output of previous command to next as an argument) but not able to get the desired result.

for i in *.txt; do
    cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1  {} >$i.sort
done

Any suggestions?

Thanks

Ron

Ron
  • 1,057

1 Answers1

2
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).

Kusalananda
  • 333,661