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
    11 hours ago













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

    – Forethinker
    10 hours ago
















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
    11 hours ago













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

    – Forethinker
    10 hours ago














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 11 hours ago









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
    11 hours ago













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

    – Forethinker
    10 hours ago














  • 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
    11 hours ago













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

    – Forethinker
    10 hours ago








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
11 hours ago







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
11 hours ago















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

– Forethinker
10 hours ago





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

– Forethinker
10 hours ago










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
    10 hours ago











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

    – Kusalananda
    10 hours ago











  • Awesome. Go zsh!

    – Forethinker
    5 hours ago











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
    10 hours ago











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

    – Kusalananda
    10 hours ago











  • Awesome. Go zsh!

    – Forethinker
    5 hours ago
















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
    10 hours ago











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

    – Kusalananda
    10 hours ago











  • Awesome. Go zsh!

    – Forethinker
    5 hours ago














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 10 hours ago

























answered 11 hours ago









KusalanandaKusalananda

131k17249409




131k17249409













  • 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
    10 hours ago











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

    – Kusalananda
    10 hours ago











  • Awesome. Go zsh!

    – Forethinker
    5 hours ago



















  • 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
    10 hours ago











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

    – Kusalananda
    10 hours ago











  • Awesome. Go zsh!

    – Forethinker
    5 hours ago

















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
10 hours ago





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
10 hours ago













@Forethinker Now fixed. Thanks for the heads up!

– Kusalananda
10 hours ago





@Forethinker Now fixed. Thanks for the heads up!

– Kusalananda
10 hours ago













Awesome. Go zsh!

– Forethinker
5 hours ago





Awesome. Go zsh!

– Forethinker
5 hours ago


















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

Polycentropodidae

Magento 2 Error message: Invalid state change requested

Paulmy