Reverse the order of file matching as arguments












2















I have a program that reads files in a certain order. For this example, they all have the same extension, txt



{program_name} {input 1...} {output}


I happen to name the output file name "a.txt" so it comes as the first result when I invoke ls, which shows the order of files being fed to this command:



{program_name} *.txt


I would like the first result to show up as the last one. How can I reverse the order of the star matching? If I need to use pipe, what's the syntax for feeding in arguments properly so that any special character or white-space will be quoted properly?










share|improve this question


















  • 1





    do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

    – mosvy
    Feb 19 at 20:02













  • @mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

    – Forethinker
    Feb 19 at 20:13
















2















I have a program that reads files in a certain order. For this example, they all have the same extension, txt



{program_name} {input 1...} {output}


I happen to name the output file name "a.txt" so it comes as the first result when I invoke ls, which shows the order of files being fed to this command:



{program_name} *.txt


I would like the first result to show up as the last one. How can I reverse the order of the star matching? If I need to use pipe, what's the syntax for feeding in arguments properly so that any special character or white-space will be quoted properly?










share|improve this question


















  • 1





    do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

    – mosvy
    Feb 19 at 20:02













  • @mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

    – Forethinker
    Feb 19 at 20:13














2












2








2








I have a program that reads files in a certain order. For this example, they all have the same extension, txt



{program_name} {input 1...} {output}


I happen to name the output file name "a.txt" so it comes as the first result when I invoke ls, which shows the order of files being fed to this command:



{program_name} *.txt


I would like the first result to show up as the last one. How can I reverse the order of the star matching? If I need to use pipe, what's the syntax for feeding in arguments properly so that any special character or white-space will be quoted properly?










share|improve this question














I have a program that reads files in a certain order. For this example, they all have the same extension, txt



{program_name} {input 1...} {output}


I happen to name the output file name "a.txt" so it comes as the first result when I invoke ls, which shows the order of files being fed to this command:



{program_name} *.txt


I would like the first result to show up as the last one. How can I reverse the order of the star matching? If I need to use pipe, what's the syntax for feeding in arguments properly so that any special character or white-space will be quoted properly?







bash shell-script pipe ls






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 19 at 19:41









ForethinkerForethinker

629720




629720








  • 1





    do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

    – mosvy
    Feb 19 at 20:02













  • @mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

    – Forethinker
    Feb 19 at 20:13














  • 1





    do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

    – mosvy
    Feb 19 at 20:02













  • @mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

    – Forethinker
    Feb 19 at 20:13








1




1





do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

– mosvy
Feb 19 at 20:02







do you need a full reverse, or just have the first argument passed as the last? In the latter case, this will do wrapper(){ f=$1; shift; your_program "$@" "$f"; }

– mosvy
Feb 19 at 20:02















@mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

– Forethinker
Feb 19 at 20:13





@mosvy Yes, the latter. This works for me. Thank you. I am still hoping for an elegant solution.

– Forethinker
Feb 19 at 20:13










1 Answer
1






active

oldest

votes


















5














Making use of zsh:



zsh -c 'program *.txt(.^on)'


The (.^on) is a zsh modifier for the *.txt pattern that makes it match only regular files (the .) and that will order (o) the resulting list in reverse (^) lexicographical order (n).



This would start a non-interactive zsh shell that would run program with the generated list of filenames as command line arguments. The command would properly handle reversing the list of arguments, even if they contained spaces or newlines etc. in the filenames.



Example:



$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt




$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt




A non-zsh solution:



set --
for fname in *.txt; do
set -- "$fname" "$@"
done

program "$@"


or, using a named array in e.g. bash,



args=()
for fname in *.txt; do
args=( "$fname" "${args[@]}" )
done

program "${args[@]}"


In both of these code snippets, an array is built up from the names matching the *.txt pattern. Each name is pushed onto the array at the front, so the effect is that the array ends up having the last name first.



In the first instance, we use the list of positional parameters as the array. That code should work in any sh-like shell.





If you just need the first name last in the list of arguments to your program, and can let the other names be in the order they are expanded in, then the following would do that (in any sh-like shell):



set -- *.txt
fname=$1
shift
program "$@" "$fname"


Alternatively, using bash-specific syntax and a named array,



args=( *.txt )
program "${args[@]:1}" "${args[0]}"


"${args[@]:1}" would expand to all elements of the args array (individually quoted) from element 1 onwards.



Testing again with echo:



$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt





share|improve this answer


























  • For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

    – Forethinker
    Feb 19 at 20:08











  • @Forethinker Now fixed. Thanks for the heads up!

    – Kusalananda
    Feb 19 at 20:34











  • Awesome. Go zsh!

    – Forethinker
    Feb 20 at 1:44











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501681%2freverse-the-order-of-file-matching-as-arguments%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









5














Making use of zsh:



zsh -c 'program *.txt(.^on)'


The (.^on) is a zsh modifier for the *.txt pattern that makes it match only regular files (the .) and that will order (o) the resulting list in reverse (^) lexicographical order (n).



This would start a non-interactive zsh shell that would run program with the generated list of filenames as command line arguments. The command would properly handle reversing the list of arguments, even if they contained spaces or newlines etc. in the filenames.



Example:



$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt




$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt




A non-zsh solution:



set --
for fname in *.txt; do
set -- "$fname" "$@"
done

program "$@"


or, using a named array in e.g. bash,



args=()
for fname in *.txt; do
args=( "$fname" "${args[@]}" )
done

program "${args[@]}"


In both of these code snippets, an array is built up from the names matching the *.txt pattern. Each name is pushed onto the array at the front, so the effect is that the array ends up having the last name first.



In the first instance, we use the list of positional parameters as the array. That code should work in any sh-like shell.





If you just need the first name last in the list of arguments to your program, and can let the other names be in the order they are expanded in, then the following would do that (in any sh-like shell):



set -- *.txt
fname=$1
shift
program "$@" "$fname"


Alternatively, using bash-specific syntax and a named array,



args=( *.txt )
program "${args[@]:1}" "${args[0]}"


"${args[@]:1}" would expand to all elements of the args array (individually quoted) from element 1 onwards.



Testing again with echo:



$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt





share|improve this answer


























  • For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

    – Forethinker
    Feb 19 at 20:08











  • @Forethinker Now fixed. Thanks for the heads up!

    – Kusalananda
    Feb 19 at 20:34











  • Awesome. Go zsh!

    – Forethinker
    Feb 20 at 1:44
















5














Making use of zsh:



zsh -c 'program *.txt(.^on)'


The (.^on) is a zsh modifier for the *.txt pattern that makes it match only regular files (the .) and that will order (o) the resulting list in reverse (^) lexicographical order (n).



This would start a non-interactive zsh shell that would run program with the generated list of filenames as command line arguments. The command would properly handle reversing the list of arguments, even if they contained spaces or newlines etc. in the filenames.



Example:



$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt




$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt




A non-zsh solution:



set --
for fname in *.txt; do
set -- "$fname" "$@"
done

program "$@"


or, using a named array in e.g. bash,



args=()
for fname in *.txt; do
args=( "$fname" "${args[@]}" )
done

program "${args[@]}"


In both of these code snippets, an array is built up from the names matching the *.txt pattern. Each name is pushed onto the array at the front, so the effect is that the array ends up having the last name first.



In the first instance, we use the list of positional parameters as the array. That code should work in any sh-like shell.





If you just need the first name last in the list of arguments to your program, and can let the other names be in the order they are expanded in, then the following would do that (in any sh-like shell):



set -- *.txt
fname=$1
shift
program "$@" "$fname"


Alternatively, using bash-specific syntax and a named array,



args=( *.txt )
program "${args[@]:1}" "${args[0]}"


"${args[@]:1}" would expand to all elements of the args array (individually quoted) from element 1 onwards.



Testing again with echo:



$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt





share|improve this answer


























  • For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

    – Forethinker
    Feb 19 at 20:08











  • @Forethinker Now fixed. Thanks for the heads up!

    – Kusalananda
    Feb 19 at 20:34











  • Awesome. Go zsh!

    – Forethinker
    Feb 20 at 1:44














5












5








5







Making use of zsh:



zsh -c 'program *.txt(.^on)'


The (.^on) is a zsh modifier for the *.txt pattern that makes it match only regular files (the .) and that will order (o) the resulting list in reverse (^) lexicographical order (n).



This would start a non-interactive zsh shell that would run program with the generated list of filenames as command line arguments. The command would properly handle reversing the list of arguments, even if they contained spaces or newlines etc. in the filenames.



Example:



$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt




$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt




A non-zsh solution:



set --
for fname in *.txt; do
set -- "$fname" "$@"
done

program "$@"


or, using a named array in e.g. bash,



args=()
for fname in *.txt; do
args=( "$fname" "${args[@]}" )
done

program "${args[@]}"


In both of these code snippets, an array is built up from the names matching the *.txt pattern. Each name is pushed onto the array at the front, so the effect is that the array ends up having the last name first.



In the first instance, we use the list of positional parameters as the array. That code should work in any sh-like shell.





If you just need the first name last in the list of arguments to your program, and can let the other names be in the order they are expanded in, then the following would do that (in any sh-like shell):



set -- *.txt
fname=$1
shift
program "$@" "$fname"


Alternatively, using bash-specific syntax and a named array,



args=( *.txt )
program "${args[@]:1}" "${args[0]}"


"${args[@]:1}" would expand to all elements of the args array (individually quoted) from element 1 onwards.



Testing again with echo:



$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt





share|improve this answer















Making use of zsh:



zsh -c 'program *.txt(.^on)'


The (.^on) is a zsh modifier for the *.txt pattern that makes it match only regular files (the .) and that will order (o) the resulting list in reverse (^) lexicographical order (n).



This would start a non-interactive zsh shell that would run program with the generated list of filenames as command line arguments. The command would properly handle reversing the list of arguments, even if they contained spaces or newlines etc. in the filenames.



Example:



$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt




$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt




A non-zsh solution:



set --
for fname in *.txt; do
set -- "$fname" "$@"
done

program "$@"


or, using a named array in e.g. bash,



args=()
for fname in *.txt; do
args=( "$fname" "${args[@]}" )
done

program "${args[@]}"


In both of these code snippets, an array is built up from the names matching the *.txt pattern. Each name is pushed onto the array at the front, so the effect is that the array ends up having the last name first.



In the first instance, we use the list of positional parameters as the array. That code should work in any sh-like shell.





If you just need the first name last in the list of arguments to your program, and can let the other names be in the order they are expanded in, then the following would do that (in any sh-like shell):



set -- *.txt
fname=$1
shift
program "$@" "$fname"


Alternatively, using bash-specific syntax and a named array,



args=( *.txt )
program "${args[@]:1}" "${args[0]}"


"${args[@]:1}" would expand to all elements of the args array (individually quoted) from element 1 onwards.



Testing again with echo:



$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt






share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 19 at 20:46

























answered Feb 19 at 19:57









KusalanandaKusalananda

137k17258426




137k17258426













  • For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

    – Forethinker
    Feb 19 at 20:08











  • @Forethinker Now fixed. Thanks for the heads up!

    – Kusalananda
    Feb 19 at 20:34











  • Awesome. Go zsh!

    – Forethinker
    Feb 20 at 1:44



















  • For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

    – Forethinker
    Feb 19 at 20:08











  • @Forethinker Now fixed. Thanks for the heads up!

    – Kusalananda
    Feb 19 at 20:34











  • Awesome. Go zsh!

    – Forethinker
    Feb 20 at 1:44

















For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

– Forethinker
Feb 19 at 20:08





For your first example, I get: a.txt b.txt d.txt c.txt even after I run zsh without .zshrc file using: zsh -d -f

– Forethinker
Feb 19 at 20:08













@Forethinker Now fixed. Thanks for the heads up!

– Kusalananda
Feb 19 at 20:34





@Forethinker Now fixed. Thanks for the heads up!

– Kusalananda
Feb 19 at 20:34













Awesome. Go zsh!

– Forethinker
Feb 20 at 1:44





Awesome. Go zsh!

– Forethinker
Feb 20 at 1:44


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501681%2freverse-the-order-of-file-matching-as-arguments%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How do I know what Microsoft account the skydrive app is syncing to?

When does type information flow backwards in C++?

Grease: Live!