Find the maximum of the lengths of all filenames in a directory

Clash Royale CLAN TAG#URR8PPP up vote
1
down vote
favorite
I have to write a script that takes a directory name as an argument and writes to standard output the maximum of the lengths of all filenames in that directory. If the functionâÂÂs argument is not a directory name, write an error message.
How can I do that
command-line scripts
add a comment |Â
up vote
1
down vote
favorite
I have to write a script that takes a directory name as an argument and writes to standard output the maximum of the lengths of all filenames in that directory. If the functionâÂÂs argument is not a directory name, write an error message.
How can I do that
command-line scripts
4
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have to write a script that takes a directory name as an argument and writes to standard output the maximum of the lengths of all filenames in that directory. If the functionâÂÂs argument is not a directory name, write an error message.
How can I do that
command-line scripts
I have to write a script that takes a directory name as an argument and writes to standard output the maximum of the lengths of all filenames in that directory. If the functionâÂÂs argument is not a directory name, write an error message.
How can I do that
command-line scripts
command-line scripts
edited Feb 5 at 21:48
Zanna
48.3k13120229
48.3k13120229
asked Feb 3 at 20:12
MA VI
82
82
4
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13
add a comment |Â
4
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13
4
4
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
A script rather than a function. This prints the number of characters in the longest filename, which is what I understood you wanted:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( ($#i > $long) )) && long=$#i
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%sn" "Not a directory"
fi
This makes use of the dotglob setting, which causes globbing with * to include hidden files. To see the effect of it, run these commands in your home directory:
ls -d *
shopt -s dotglob
ls -d *
To turn off shopt settings, use -u for example shopt -u dotglob.
We need to check the argument is a directory, so we use if and the test command (in its [ form) which has a test for directories, -d:
if [ -d "$1" ]; then
this means, if the first argument passed to the script is the name of a directory that exists, then do the following. $1 is the first argument, and we enclose it in double quotes to stop the shell from performing further expansions on the value of the variable.
We need to go into the directory, because we need to get the length of the filename, not the whole path (absolute or relative). We don't want this:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
because if we count the length of $i we will get the length of the full path. We could do some text processing antics (and maybe some cleverer tricks I don't know) to get rid of the path, but parsing filenames is generally unreliable and if we change directory we can easily get the shell to count characters for us using $#var to give the length of var (I believe that this counts characters and not bytes). Note that scripts run in a child shell, not in the current shell, so if a script changes directory, the working directory of the shell that calls the script isn't affected.
My script uses for to loop over the files in the directory. The line that does the work is
(( ($#i > $long) )) && long=$#i
This means, if the length of the current value of i is greater than the current value of long, then assign the length of i to long. Since we first set long to 0, the first filename will always be longer than long (because it's as short as possible). Thereafter, only the length of longer filenames will be able to replace the value of long. Since we know $#i and long will only contain integers, we don't need to protect them with double quotes. (( creates an arithmetic context in Bash so we can use > with its mathematical meaning (thanks to muru for pointing that out to me elsewhere).
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
A script rather than a function. This prints the number of characters in the longest filename, which is what I understood you wanted:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( ($#i > $long) )) && long=$#i
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%sn" "Not a directory"
fi
This makes use of the dotglob setting, which causes globbing with * to include hidden files. To see the effect of it, run these commands in your home directory:
ls -d *
shopt -s dotglob
ls -d *
To turn off shopt settings, use -u for example shopt -u dotglob.
We need to check the argument is a directory, so we use if and the test command (in its [ form) which has a test for directories, -d:
if [ -d "$1" ]; then
this means, if the first argument passed to the script is the name of a directory that exists, then do the following. $1 is the first argument, and we enclose it in double quotes to stop the shell from performing further expansions on the value of the variable.
We need to go into the directory, because we need to get the length of the filename, not the whole path (absolute or relative). We don't want this:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
because if we count the length of $i we will get the length of the full path. We could do some text processing antics (and maybe some cleverer tricks I don't know) to get rid of the path, but parsing filenames is generally unreliable and if we change directory we can easily get the shell to count characters for us using $#var to give the length of var (I believe that this counts characters and not bytes). Note that scripts run in a child shell, not in the current shell, so if a script changes directory, the working directory of the shell that calls the script isn't affected.
My script uses for to loop over the files in the directory. The line that does the work is
(( ($#i > $long) )) && long=$#i
This means, if the length of the current value of i is greater than the current value of long, then assign the length of i to long. Since we first set long to 0, the first filename will always be longer than long (because it's as short as possible). Thereafter, only the length of longer filenames will be able to replace the value of long. Since we know $#i and long will only contain integers, we don't need to protect them with double quotes. (( creates an arithmetic context in Bash so we can use > with its mathematical meaning (thanks to muru for pointing that out to me elsewhere).
add a comment |Â
up vote
2
down vote
accepted
A script rather than a function. This prints the number of characters in the longest filename, which is what I understood you wanted:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( ($#i > $long) )) && long=$#i
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%sn" "Not a directory"
fi
This makes use of the dotglob setting, which causes globbing with * to include hidden files. To see the effect of it, run these commands in your home directory:
ls -d *
shopt -s dotglob
ls -d *
To turn off shopt settings, use -u for example shopt -u dotglob.
We need to check the argument is a directory, so we use if and the test command (in its [ form) which has a test for directories, -d:
if [ -d "$1" ]; then
this means, if the first argument passed to the script is the name of a directory that exists, then do the following. $1 is the first argument, and we enclose it in double quotes to stop the shell from performing further expansions on the value of the variable.
We need to go into the directory, because we need to get the length of the filename, not the whole path (absolute or relative). We don't want this:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
because if we count the length of $i we will get the length of the full path. We could do some text processing antics (and maybe some cleverer tricks I don't know) to get rid of the path, but parsing filenames is generally unreliable and if we change directory we can easily get the shell to count characters for us using $#var to give the length of var (I believe that this counts characters and not bytes). Note that scripts run in a child shell, not in the current shell, so if a script changes directory, the working directory of the shell that calls the script isn't affected.
My script uses for to loop over the files in the directory. The line that does the work is
(( ($#i > $long) )) && long=$#i
This means, if the length of the current value of i is greater than the current value of long, then assign the length of i to long. Since we first set long to 0, the first filename will always be longer than long (because it's as short as possible). Thereafter, only the length of longer filenames will be able to replace the value of long. Since we know $#i and long will only contain integers, we don't need to protect them with double quotes. (( creates an arithmetic context in Bash so we can use > with its mathematical meaning (thanks to muru for pointing that out to me elsewhere).
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
A script rather than a function. This prints the number of characters in the longest filename, which is what I understood you wanted:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( ($#i > $long) )) && long=$#i
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%sn" "Not a directory"
fi
This makes use of the dotglob setting, which causes globbing with * to include hidden files. To see the effect of it, run these commands in your home directory:
ls -d *
shopt -s dotglob
ls -d *
To turn off shopt settings, use -u for example shopt -u dotglob.
We need to check the argument is a directory, so we use if and the test command (in its [ form) which has a test for directories, -d:
if [ -d "$1" ]; then
this means, if the first argument passed to the script is the name of a directory that exists, then do the following. $1 is the first argument, and we enclose it in double quotes to stop the shell from performing further expansions on the value of the variable.
We need to go into the directory, because we need to get the length of the filename, not the whole path (absolute or relative). We don't want this:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
because if we count the length of $i we will get the length of the full path. We could do some text processing antics (and maybe some cleverer tricks I don't know) to get rid of the path, but parsing filenames is generally unreliable and if we change directory we can easily get the shell to count characters for us using $#var to give the length of var (I believe that this counts characters and not bytes). Note that scripts run in a child shell, not in the current shell, so if a script changes directory, the working directory of the shell that calls the script isn't affected.
My script uses for to loop over the files in the directory. The line that does the work is
(( ($#i > $long) )) && long=$#i
This means, if the length of the current value of i is greater than the current value of long, then assign the length of i to long. Since we first set long to 0, the first filename will always be longer than long (because it's as short as possible). Thereafter, only the length of longer filenames will be able to replace the value of long. Since we know $#i and long will only contain integers, we don't need to protect them with double quotes. (( creates an arithmetic context in Bash so we can use > with its mathematical meaning (thanks to muru for pointing that out to me elsewhere).
A script rather than a function. This prints the number of characters in the longest filename, which is what I understood you wanted:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( ($#i > $long) )) && long=$#i
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%sn" "Not a directory"
fi
This makes use of the dotglob setting, which causes globbing with * to include hidden files. To see the effect of it, run these commands in your home directory:
ls -d *
shopt -s dotglob
ls -d *
To turn off shopt settings, use -u for example shopt -u dotglob.
We need to check the argument is a directory, so we use if and the test command (in its [ form) which has a test for directories, -d:
if [ -d "$1" ]; then
this means, if the first argument passed to the script is the name of a directory that exists, then do the following. $1 is the first argument, and we enclose it in double quotes to stop the shell from performing further expansions on the value of the variable.
We need to go into the directory, because we need to get the length of the filename, not the whole path (absolute or relative). We don't want this:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
because if we count the length of $i we will get the length of the full path. We could do some text processing antics (and maybe some cleverer tricks I don't know) to get rid of the path, but parsing filenames is generally unreliable and if we change directory we can easily get the shell to count characters for us using $#var to give the length of var (I believe that this counts characters and not bytes). Note that scripts run in a child shell, not in the current shell, so if a script changes directory, the working directory of the shell that calls the script isn't affected.
My script uses for to loop over the files in the directory. The line that does the work is
(( ($#i > $long) )) && long=$#i
This means, if the length of the current value of i is greater than the current value of long, then assign the length of i to long. Since we first set long to 0, the first filename will always be longer than long (because it's as short as possible). Thereafter, only the length of longer filenames will be able to replace the value of long. Since we know $#i and long will only contain integers, we don't need to protect them with double quotes. (( creates an arithmetic context in Bash so we can use > with its mathematical meaning (thanks to muru for pointing that out to me elsewhere).
edited Feb 15 at 19:15
answered Feb 5 at 22:28
Zanna
48.3k13120229
48.3k13120229
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1002753%2ffind-the-maximum-of-the-lengths-of-all-filenames-in-a-directory%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
4
Welcome to Ask Ubuntu! You seem to be asking a "Give me a fish question". Both you and those who find your question later would be best served by a "How to Fish answer". You will likely get more focused answers if you edit your question to show what you have tried and where you are having trouble.
â J. Starnes
Feb 3 at 20:32
I am not seeing how this question is too broad... printing an error message if a condition is not met seems pretty reasonable to me! How would this benefit from being narrowed down?
â Zanna
Feb 5 at 22:33
What have you done already? Do you have an approach that you've already tried? Can you ask about a specific problem that you've had while trying this for yourself? If you haven't tried anything yet, then you're just asking someone on Ask Ubuntu to do work for you; that's not what the site is for.
â Jeremy Kerr
Feb 7 at 2:13