It is not safe to parse ls
or to pipe find
[1,2]
It is not safe to parse (and to pipe) the output of ls
or find
, mainly because it possible to find in the file names non usual characters as the newline, the tab... Here a pure shell cycle will work[cuonglm].
Even the find
command not piped with the option -exec
will work:
find ./*.png -exec basename {} .png \;
Updates/Notes: You can use find .
to search even for the hidden files, or find ./*.png
to get only the not hidden ones. With find *.png -exec ...
you can have problem in the case it was present a file named .png
because find will get it as an option. You can add -maxdepth 0
to avoid to descend in directories named as Dir_01.png
, or find ./*.png -prune -exec ...
when maxdepth is not allowed (thanks Stéphane). If you want to avoid to list those directories you should add the option -type f
(which would also exclude other types of non-regular files). Give it a look to the man
for a more complete panorama about all the options available, and remember to check when they are POSIX compliant, for a better portability.
Some words more
It can happen, for example, that copying the title from a document and pasting into the filename, one or more newline will finish in the filename itself. We can be even so unlucky that a title can contain even the key we have to use just before a newline:
The new art of working on .png
files and other formats.
If you want to test, you can create file names like this with the commands
touch "A file with two lines"$'\n'"and This is the second.png"
touch "The new art of working on .png"$'\n'"files and other formats.png"
The simple /bin/ls *png
will output ?
instead of the non printable characters
A file with two lines?and This is the second.png
The new art of working on .png?files and other formats.png
In all the cases in which you will pipe the output of ls
or find
the following command will have no hint to understand if the present line comes from a new file name or if it follows a newline character in the precedent file name. A nasty name indeed, but still a legal one.
A shell cycle with a shell Parameter-Expansion , ${parameter%word}
, in both the variant with printf
or echo
will work [cuonglm],[Anthon1] .
for f in *.png; do printf "%s\n" "${f%.png}" ; done
From the man page of the Shell Parameter Expansion [3]
${parameter%word}
${parameter%%word}
... the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted.
.
in them. Although the convention says to name your files with.png
at the end, there is no reason why I can't have a png file namedfoo.zip
ormy.picture.20160518
or justmypic
.ls
and to pipe the output ofls
andfind
, mainly because the possibility to incur innewline
,` tab char in the file name. If the filename isThe new art of working on .png\NEWLINE files and other formats
many of the solution proposed will create problems.