Cannot sort my bash functions correctlySort based on comma separated wordsWhat is the fastest way to sort a...

Concat Loop Results to determine if contains value

Is there a way to count the number of lines of text in a file including non-delimited ones?

Are there really no countries that protect Freedom of Speech as the United States does?

Can I enter the USA with an E-2 visa and a one way flight ticket?

What is the difference between 王 and 皇?

If I animate and control a zombie, does it benefit from Undead Fortitude when it's reduced to 0 HP?

Is it okay for a ticket seller to grab a tip in the USA?

Website error: "Walmart can’t use this browser"

How much can I judge a company based on a phone screening?

How would timezones work on a planet 100 times the size of our Earth

Why is Python 2.7 still the default Python version in Ubuntu?

Why aren't rainbows blurred-out into nothing after they are produced?

An equality about sin function?

Will using a resistor in series with a LED to control its voltage increase the total energy expenditure?

Translation of "I don't have anything to smile about"

Escape Velocity - Won't the orbital path just become larger with higher initial velocity?

Can lodestones be used to magnetize crude iron weapons?

How far did Gandalf and the Balrog drop from the bridge in Moria?

Why command hierarchy, if the chain of command is standing next to each other?

Why are Tucker and Malcolm not dead?

How is являться different from есть and быть

Can the IPA represent all languages' tones?

Is this n-speak?

Programmatically add log information in all renderings(controller, view) html



Cannot sort my bash functions correctly


Sort based on comma separated wordsWhat is the fastest way to sort a paragraph?Why is bash not interactive after setting &shell='/bin/bash -i'?Sort every few linesHow can I sort a file by word frequency?Why doesn't vim recognize bash self-made functionsSorted TODO list with :sort n and lettersIs there an efficient way to sort a selection of comma separated values in a single line?function: sort output alphabetically






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







3















I'm trying to sort my bash functions inside my .bash_functions file.



Here is what I type :



:g/^function /,/^}$/ s/n/@@@
:sort /^function /
:%s/@@@/r/g


EDIT0 : Here is some of the input :



function listVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# echo $(youtube-dl -g "$rssURL")
echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {
test $# = 0 && {
echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2
return 1
}

local angle=$1
shift
for pic
do
extension="${pic/*./}"
newFile="${pic/.$extension/_ROTATED.$extension}"
echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2
jpegtran -perfect -rotate $angle "$pic" > "$newFile"
touch -r "$pic" "$newFile"
done
}


Something is wrong with my first command because the functions' code should be converted into one liners.



However, here is a little piece of the output I get instead :



function listVideosFromRSSPodCastPlayList {@@@  test $# = 1 && {@@@     local rssURL="$1"@@@        local wget="$(which wget2 2>/dev/null || which wget)"@@@#       echo $(youtube-dl -g "$rssURL")@@@      echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)@@@    }@@@}@@@function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {@@@ test $# = 0 && {@@@ echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2@@@ return 1@@@ }@@@@@@ local angle=$1@@@ shift@@@ for pic@@@ do@@@ extension="${pic/*./}"@@@ newFile="${pic/.$extension/_ROTATED.$extension}"@@@ echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2@@@ jpegtran -perfect -rotate $angle "$pic" > "$newFile"@@@ touch -r "$pic" "$newFile"@@@ done@@@}@@@function locateBin {
local regExp="$1"
shift
locate "bin/.*$regExp" "$@"
}
...


Can you help me ?










share|improve this question



























  • Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

    – D. Ben Knoble
    19 hours ago











  • As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

    – D. Ben Knoble
    12 hours ago


















3















I'm trying to sort my bash functions inside my .bash_functions file.



Here is what I type :



:g/^function /,/^}$/ s/n/@@@
:sort /^function /
:%s/@@@/r/g


EDIT0 : Here is some of the input :



function listVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# echo $(youtube-dl -g "$rssURL")
echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {
test $# = 0 && {
echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2
return 1
}

local angle=$1
shift
for pic
do
extension="${pic/*./}"
newFile="${pic/.$extension/_ROTATED.$extension}"
echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2
jpegtran -perfect -rotate $angle "$pic" > "$newFile"
touch -r "$pic" "$newFile"
done
}


Something is wrong with my first command because the functions' code should be converted into one liners.



However, here is a little piece of the output I get instead :



function listVideosFromRSSPodCastPlayList {@@@  test $# = 1 && {@@@     local rssURL="$1"@@@        local wget="$(which wget2 2>/dev/null || which wget)"@@@#       echo $(youtube-dl -g "$rssURL")@@@      echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)@@@    }@@@}@@@function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {@@@ test $# = 0 && {@@@ echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2@@@ return 1@@@ }@@@@@@ local angle=$1@@@ shift@@@ for pic@@@ do@@@ extension="${pic/*./}"@@@ newFile="${pic/.$extension/_ROTATED.$extension}"@@@ echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2@@@ jpegtran -perfect -rotate $angle "$pic" > "$newFile"@@@ touch -r "$pic" "$newFile"@@@ done@@@}@@@function locateBin {
local regExp="$1"
shift
locate "bin/.*$regExp" "$@"
}
...


Can you help me ?










share|improve this question



























  • Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

    – D. Ben Knoble
    19 hours ago











  • As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

    – D. Ben Knoble
    12 hours ago














3












3








3


1






I'm trying to sort my bash functions inside my .bash_functions file.



Here is what I type :



:g/^function /,/^}$/ s/n/@@@
:sort /^function /
:%s/@@@/r/g


EDIT0 : Here is some of the input :



function listVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# echo $(youtube-dl -g "$rssURL")
echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {
test $# = 0 && {
echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2
return 1
}

local angle=$1
shift
for pic
do
extension="${pic/*./}"
newFile="${pic/.$extension/_ROTATED.$extension}"
echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2
jpegtran -perfect -rotate $angle "$pic" > "$newFile"
touch -r "$pic" "$newFile"
done
}


Something is wrong with my first command because the functions' code should be converted into one liners.



However, here is a little piece of the output I get instead :



function listVideosFromRSSPodCastPlayList {@@@  test $# = 1 && {@@@     local rssURL="$1"@@@        local wget="$(which wget2 2>/dev/null || which wget)"@@@#       echo $(youtube-dl -g "$rssURL")@@@      echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)@@@    }@@@}@@@function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {@@@ test $# = 0 && {@@@ echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2@@@ return 1@@@ }@@@@@@ local angle=$1@@@ shift@@@ for pic@@@ do@@@ extension="${pic/*./}"@@@ newFile="${pic/.$extension/_ROTATED.$extension}"@@@ echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2@@@ jpegtran -perfect -rotate $angle "$pic" > "$newFile"@@@ touch -r "$pic" "$newFile"@@@ done@@@}@@@function locateBin {
local regExp="$1"
shift
locate "bin/.*$regExp" "$@"
}
...


Can you help me ?










share|improve this question
















I'm trying to sort my bash functions inside my .bash_functions file.



Here is what I type :



:g/^function /,/^}$/ s/n/@@@
:sort /^function /
:%s/@@@/r/g


EDIT0 : Here is some of the input :



function listVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# echo $(youtube-dl -g "$rssURL")
echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {
test $# = 0 && {
echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2
return 1
}

local angle=$1
shift
for pic
do
extension="${pic/*./}"
newFile="${pic/.$extension/_ROTATED.$extension}"
echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2
jpegtran -perfect -rotate $angle "$pic" > "$newFile"
touch -r "$pic" "$newFile"
done
}


Something is wrong with my first command because the functions' code should be converted into one liners.



However, here is a little piece of the output I get instead :



function listVideosFromRSSPodCastPlayList {@@@  test $# = 1 && {@@@     local rssURL="$1"@@@        local wget="$(which wget2 2>/dev/null || which wget)"@@@#       echo $(youtube-dl -g "$rssURL")@@@      echo $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)@@@    }@@@}@@@function getVideosFromRSSPodCastPlayList {
test $# = 1 && {
local rssURL="$1"
local wget="$(which wget2 2>/dev/null || which wget)"
# $wget $(youtube-dl -g "$rssURL")
$wget $(curl -s "$rssURL" | egrep -o "https?:[^ <>]*(mp4|webm)" | grep -v .google.com/ | uniq)
}
}
function jpgRotate {@@@ test $# = 0 && {@@@ echo "=> Usage: $FUNCNAME angle file1 file2 file3 ..." >&2@@@ return 1@@@ }@@@@@@ local angle=$1@@@ shift@@@ for pic@@@ do@@@ extension="${pic/*./}"@@@ newFile="${pic/.$extension/_ROTATED.$extension}"@@@ echo "=> Losslessly rotating $pic by $angle degrees into $newFile ..." >&2@@@ jpegtran -perfect -rotate $angle "$pic" > "$newFile"@@@ touch -r "$pic" "$newFile"@@@ done@@@}@@@function locateBin {
local regExp="$1"
shift
locate "bin/.*$regExp" "$@"
}
...


Can you help me ?







bash sort






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 15 hours ago







SebMa

















asked yesterday









SebMaSebMa

2442 silver badges9 bronze badges




2442 silver badges9 bronze badges
















  • Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

    – D. Ben Knoble
    19 hours ago











  • As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

    – D. Ben Knoble
    12 hours ago



















  • Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

    – D. Ben Knoble
    19 hours ago











  • As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

    – D. Ben Knoble
    12 hours ago

















Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

– D. Ben Knoble
19 hours ago





Can you provide the original input? I suspect there are braces inside the functions, causing the schwartzian transform to not cover the entire text

– D. Ben Knoble
19 hours ago













As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

– D. Ben Knoble
12 hours ago





As expected, you global command range falls short and/or @@@ is a bad delimiter. Maybe try ::: ?

– D. Ben Knoble
12 hours ago










1 Answer
1






active

oldest

votes


















4














Try to add the negative offset -1 to the second line specifier in the range passed to the first substitution command:



                   v
:g/^function /,/^}/- s/n/@@@
:sort /^function /
:%s/@@@/r/g


Otherwise, the newline at the end of your first function is replaced with @@@, which wrongly merges the first line of the second function with the last line of the first one.






the last substition does not work correctly for input lines already ending with @ (for example : echo $@)




In your substitution commands, you need to use a text which doesn't appear in your file.
A good candidate for this kind of transformation is a non-printing character such as a control character like a literal C-a whose caret notation is ^A.
Try this instead:



:exe "g/^function /,/^}/- s/\n/<c-a>"
:sort /^function /
:exe "%s/<c-a>/\r/g"



why bother with the "exe" command, extra quotes and extra backslashes which makes this harder to read ?




The original command that I posted worked on your input file. Now, you say that it doesn't work on another input file which contains echo $@, so I use a non-printing character for the replacement.



It works without the exe and the extra backslashes, but in this case your replacement is just the text <c-a>. And there's no guarantee it will work on some other input file you encounter in the future. OTOH, ^A is unlikely to appear in your bash script files 1, so there should be no issue.



If you agree, then you need exe, the quotes, and the extra backslashes to make Vim translate <c-a> into ^A (see :h expr-quote).



You can see the result of the translation by replacing exe with echo:



:echo "g/^function /,/^}/- s/\n/<c-a>"
g/^function /,/^}/- s/n/^A
^^

:echo "%s/<c-a>/\r/g"
%s/^A/r/g
^^




1 If you need to write ^A in one of your bash script, try $'ca'.



$ printf '%s' $'ca' | od -tc
0000000 001
0000001


The syntax is documented in the QUOTING section from $ man bash:




Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:



...



cx a control-x character







share|improve this answer























  • 1





    Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

    – SebMa
    14 hours ago













  • @SebMa you dont have to accepf an answer that doesnt work

    – D. Ben Knoble
    12 hours ago











  • @user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

    – SebMa
    12 hours ago








  • 1





    @SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

    – Jürgen Krämer
    8 hours ago






  • 1





    So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

    – user938271
    6 hours ago














Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "599"
};
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%2fvi.stackexchange.com%2fquestions%2f20879%2fcannot-sort-my-bash-functions-correctly%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









4














Try to add the negative offset -1 to the second line specifier in the range passed to the first substitution command:



                   v
:g/^function /,/^}/- s/n/@@@
:sort /^function /
:%s/@@@/r/g


Otherwise, the newline at the end of your first function is replaced with @@@, which wrongly merges the first line of the second function with the last line of the first one.






the last substition does not work correctly for input lines already ending with @ (for example : echo $@)




In your substitution commands, you need to use a text which doesn't appear in your file.
A good candidate for this kind of transformation is a non-printing character such as a control character like a literal C-a whose caret notation is ^A.
Try this instead:



:exe "g/^function /,/^}/- s/\n/<c-a>"
:sort /^function /
:exe "%s/<c-a>/\r/g"



why bother with the "exe" command, extra quotes and extra backslashes which makes this harder to read ?




The original command that I posted worked on your input file. Now, you say that it doesn't work on another input file which contains echo $@, so I use a non-printing character for the replacement.



It works without the exe and the extra backslashes, but in this case your replacement is just the text <c-a>. And there's no guarantee it will work on some other input file you encounter in the future. OTOH, ^A is unlikely to appear in your bash script files 1, so there should be no issue.



If you agree, then you need exe, the quotes, and the extra backslashes to make Vim translate <c-a> into ^A (see :h expr-quote).



You can see the result of the translation by replacing exe with echo:



:echo "g/^function /,/^}/- s/\n/<c-a>"
g/^function /,/^}/- s/n/^A
^^

:echo "%s/<c-a>/\r/g"
%s/^A/r/g
^^




1 If you need to write ^A in one of your bash script, try $'ca'.



$ printf '%s' $'ca' | od -tc
0000000 001
0000001


The syntax is documented in the QUOTING section from $ man bash:




Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:



...



cx a control-x character







share|improve this answer























  • 1





    Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

    – SebMa
    14 hours ago













  • @SebMa you dont have to accepf an answer that doesnt work

    – D. Ben Knoble
    12 hours ago











  • @user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

    – SebMa
    12 hours ago








  • 1





    @SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

    – Jürgen Krämer
    8 hours ago






  • 1





    So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

    – user938271
    6 hours ago
















4














Try to add the negative offset -1 to the second line specifier in the range passed to the first substitution command:



                   v
:g/^function /,/^}/- s/n/@@@
:sort /^function /
:%s/@@@/r/g


Otherwise, the newline at the end of your first function is replaced with @@@, which wrongly merges the first line of the second function with the last line of the first one.






the last substition does not work correctly for input lines already ending with @ (for example : echo $@)




In your substitution commands, you need to use a text which doesn't appear in your file.
A good candidate for this kind of transformation is a non-printing character such as a control character like a literal C-a whose caret notation is ^A.
Try this instead:



:exe "g/^function /,/^}/- s/\n/<c-a>"
:sort /^function /
:exe "%s/<c-a>/\r/g"



why bother with the "exe" command, extra quotes and extra backslashes which makes this harder to read ?




The original command that I posted worked on your input file. Now, you say that it doesn't work on another input file which contains echo $@, so I use a non-printing character for the replacement.



It works without the exe and the extra backslashes, but in this case your replacement is just the text <c-a>. And there's no guarantee it will work on some other input file you encounter in the future. OTOH, ^A is unlikely to appear in your bash script files 1, so there should be no issue.



If you agree, then you need exe, the quotes, and the extra backslashes to make Vim translate <c-a> into ^A (see :h expr-quote).



You can see the result of the translation by replacing exe with echo:



:echo "g/^function /,/^}/- s/\n/<c-a>"
g/^function /,/^}/- s/n/^A
^^

:echo "%s/<c-a>/\r/g"
%s/^A/r/g
^^




1 If you need to write ^A in one of your bash script, try $'ca'.



$ printf '%s' $'ca' | od -tc
0000000 001
0000001


The syntax is documented in the QUOTING section from $ man bash:




Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:



...



cx a control-x character







share|improve this answer























  • 1





    Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

    – SebMa
    14 hours ago













  • @SebMa you dont have to accepf an answer that doesnt work

    – D. Ben Knoble
    12 hours ago











  • @user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

    – SebMa
    12 hours ago








  • 1





    @SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

    – Jürgen Krämer
    8 hours ago






  • 1





    So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

    – user938271
    6 hours ago














4












4








4







Try to add the negative offset -1 to the second line specifier in the range passed to the first substitution command:



                   v
:g/^function /,/^}/- s/n/@@@
:sort /^function /
:%s/@@@/r/g


Otherwise, the newline at the end of your first function is replaced with @@@, which wrongly merges the first line of the second function with the last line of the first one.






the last substition does not work correctly for input lines already ending with @ (for example : echo $@)




In your substitution commands, you need to use a text which doesn't appear in your file.
A good candidate for this kind of transformation is a non-printing character such as a control character like a literal C-a whose caret notation is ^A.
Try this instead:



:exe "g/^function /,/^}/- s/\n/<c-a>"
:sort /^function /
:exe "%s/<c-a>/\r/g"



why bother with the "exe" command, extra quotes and extra backslashes which makes this harder to read ?




The original command that I posted worked on your input file. Now, you say that it doesn't work on another input file which contains echo $@, so I use a non-printing character for the replacement.



It works without the exe and the extra backslashes, but in this case your replacement is just the text <c-a>. And there's no guarantee it will work on some other input file you encounter in the future. OTOH, ^A is unlikely to appear in your bash script files 1, so there should be no issue.



If you agree, then you need exe, the quotes, and the extra backslashes to make Vim translate <c-a> into ^A (see :h expr-quote).



You can see the result of the translation by replacing exe with echo:



:echo "g/^function /,/^}/- s/\n/<c-a>"
g/^function /,/^}/- s/n/^A
^^

:echo "%s/<c-a>/\r/g"
%s/^A/r/g
^^




1 If you need to write ^A in one of your bash script, try $'ca'.



$ printf '%s' $'ca' | od -tc
0000000 001
0000001


The syntax is documented in the QUOTING section from $ man bash:




Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:



...



cx a control-x character







share|improve this answer















Try to add the negative offset -1 to the second line specifier in the range passed to the first substitution command:



                   v
:g/^function /,/^}/- s/n/@@@
:sort /^function /
:%s/@@@/r/g


Otherwise, the newline at the end of your first function is replaced with @@@, which wrongly merges the first line of the second function with the last line of the first one.






the last substition does not work correctly for input lines already ending with @ (for example : echo $@)




In your substitution commands, you need to use a text which doesn't appear in your file.
A good candidate for this kind of transformation is a non-printing character such as a control character like a literal C-a whose caret notation is ^A.
Try this instead:



:exe "g/^function /,/^}/- s/\n/<c-a>"
:sort /^function /
:exe "%s/<c-a>/\r/g"



why bother with the "exe" command, extra quotes and extra backslashes which makes this harder to read ?




The original command that I posted worked on your input file. Now, you say that it doesn't work on another input file which contains echo $@, so I use a non-printing character for the replacement.



It works without the exe and the extra backslashes, but in this case your replacement is just the text <c-a>. And there's no guarantee it will work on some other input file you encounter in the future. OTOH, ^A is unlikely to appear in your bash script files 1, so there should be no issue.



If you agree, then you need exe, the quotes, and the extra backslashes to make Vim translate <c-a> into ^A (see :h expr-quote).



You can see the result of the translation by replacing exe with echo:



:echo "g/^function /,/^}/- s/\n/<c-a>"
g/^function /,/^}/- s/n/^A
^^

:echo "%s/<c-a>/\r/g"
%s/^A/r/g
^^




1 If you need to write ^A in one of your bash script, try $'ca'.



$ printf '%s' $'ca' | od -tc
0000000 001
0000001


The syntax is documented in the QUOTING section from $ man bash:




Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:



...



cx a control-x character








share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago

























answered 23 hours ago









user938271user938271

1,0971 gold badge3 silver badges8 bronze badges




1,0971 gold badge3 silver badges8 bronze badges











  • 1





    Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

    – SebMa
    14 hours ago













  • @SebMa you dont have to accepf an answer that doesnt work

    – D. Ben Knoble
    12 hours ago











  • @user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

    – SebMa
    12 hours ago








  • 1





    @SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

    – Jürgen Krämer
    8 hours ago






  • 1





    So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

    – user938271
    6 hours ago














  • 1





    Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

    – SebMa
    14 hours ago













  • @SebMa you dont have to accepf an answer that doesnt work

    – D. Ben Knoble
    12 hours ago











  • @user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

    – SebMa
    12 hours ago








  • 1





    @SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

    – Jürgen Krämer
    8 hours ago






  • 1





    So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

    – user938271
    6 hours ago








1




1





Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

– SebMa
14 hours ago







Something is wrong in the case where a line ends with $@, then after the first substitution command, this line ends with $@@@@ and the then the last substitution command replaces $@@@@ by r@ instead of @r, can you please update your last substitution command ?

– SebMa
14 hours ago















@SebMa you dont have to accepf an answer that doesnt work

– D. Ben Knoble
12 hours ago





@SebMa you dont have to accepf an answer that doesnt work

– D. Ben Knoble
12 hours ago













@user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

– SebMa
12 hours ago







@user938271 I'm sorry but it looks I accepted your answer too soon, the last substition does not work correctly for input lines already ending with @ (for example : echo $@)

– SebMa
12 hours ago






1




1





@SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

– Jürgen Krämer
8 hours ago





@SebMa A "placeholder" is nothing specific to Vim. I meant the three commercial-at signs, which you used as a marker for end-of-line.

– Jürgen Krämer
8 hours ago




1




1





So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

– user938271
6 hours ago





So now, I post what I wanted to initially, because that's what I use all the time. I never use a temporary replacement using printing characters, because it caused me too many issues in the past, and because Vimscript has enough pitfalls to avoid. But again, use whatever you prefer.

– user938271
6 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Vi and Vim 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%2fvi.stackexchange.com%2fquestions%2f20879%2fcannot-sort-my-bash-functions-correctly%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

Hudson River Historic District Contents Geography History The district today Aesthetics Cultural...

The number designs the writing. Feandra Aversely Definition: The act of ingrafting a sprig or shoot of one...

Ayherre Geografie Demografie Externe links Navigatiemenu43° 23′ NB, 1° 15′ WL43° 23′ NB, 1°...