0

I'm trying to write a script which identifies name groups from the filenames of photos exported out of the Photo app, creates directories out of those filenames, and then puts the same photos into their corresponding directories. E.g. "Oranges1.jpg" and "Oranges5.jpg" get put into a directory labeled "Oranges".

The first part I have no trouble with. The second part, with moving the files into the directories, has me stumped. I have the files in one folder on my desktop, I created the new folders in a separate one, and I'm using this variable in a for loop:

SEARCH=$(ls /Users/ithomas/Desktop/files/ | grep ${DIR#*directories/})

Where $DIR is just the name of each newly created directory I'm moving everything to. I've verified that my $SEARCH variable compares the filenames and folder names effectively, but the output always looks like this:

Fifth Grade Elements of Art - 1 of 2.jpeg

which means I can't pipe it into mv to send it to the appropriate folder because there are no escape characters.

Is there a way to reintroduce the escape characters to the stdout or is there another method I might use?

ee_un
  • 1
  • 2
    [Don't use `ls`](http://mywiki.wooledge.org/ParsingLs); use either a `for file in /Users/ithomas/Desktop/files/*` loop or `find ... -print0 | while IFS= read -rd '' file` loop. If you need to store all the filenames, use an array with each filename as a separate element. Do *not* put escapes and quotes in your data and expect them to be treated as shell syntax. See [BashFAQ #20: "How can I find and safely handle file names containing newlines, spaces or both?"](http://mywiki.wooledge.org/BashFAQ/020) – Gordon Davisson Sep 23 '22 at 21:01
  • Note that while _some_ of the answers on the linked duplicate only cover fixing support for filenames with spaces, the proper ones -- suggesting `find ... -print0` or `find ... -exec` -- do support all possible filenames. In addition to the BashFAQ #20 link above, also see [Using Find](https://mywiki.wooledge.org/UsingFind). – Charles Duffy Sep 23 '22 at 21:11
  • Note that a NUL-delimited stream, like that from `find -print0`, can also be generated by GNU grep using the `-z` argument. And, as Using Find indicates, one can use `-exec` as a test as opposed to a terminal action: `find . -name '*.txt' -exec grep -qe foo '{}' ';' -print` will print only filenames where `grep` indicated that the file contained `foo`. – Charles Duffy Sep 23 '22 at 21:14
  • BTW -- note that escape characters are _syntax_; they're not data. When you run `ls 'two words'` or `ls two\ words`, the `'`s or the backslash aren't sent to `ls`. Instead, it's given an array of C strings that have already had shell syntax stripped from them; in JSON, it would look like `["/bin/ls", "two words"]` -- **not** `["/bin/ls", "'two words'"]` or `["/bin/ls", "two\\ words"]`. – Charles Duffy Sep 23 '22 at 21:17
  • Thanks for all your advice, guys. I really appreciate it! – ee_un Sep 26 '22 at 17:15

0 Answers0