Friday, April 12, 2019

Add folder name to file name linux

I had a bunch of misnamed files throughout a directory tree that I had to fix the names of to have a common prefix with the name of their folder appended. Actually it was the name of a folder two levels up.

Theoretically a single-line 'find' command with the right -exec should be possible. However, encapsulating an awk script within a mv command hanging off of find, even with xargs proved to be too tricky, and I ended up just creating an echo statement with the mv commands and then taking the echoed output and putting it into a shell script.

Here is the final find-xargs-awk command line which generated the stdout that I pasted into my shell script. In this case, the original files are in ./$TL/$SL/ and $TL is a date code and I wanted to find the oldfile which had the wrong date code on the front and rename it to a new file prefix with the desired datecode on the end:
find . -name "*oldfile.csv" | xargs -I '{}' echo {} | awk -F'/' '{SL = NF-1; TL = NF-2; print "mv " $FILENAME "./" $TL "/" $SL "/newfile_" $TL ".csv"}'

Here are some relevant links turned up during researching this:

Here's a super simple example of using find to rename files. The commenter here likes xargs too much when it's unnecessary: https://unix.stackexchange.com/questions/227662/how-to-rename-multiple-files-using-find
I tried using SED to split up the directory path but it's way too hard to get it to treat slashes as delimiters, plus the result keeps the delimiter for some reason: https://stackoverflow.com/questions/16643288/sed-to-extract-text-between-two-strings
Still trying to get sed to work, here is a nice comparison of the same task with parentheses in different languages: https://unix.stackexchange.com/questions/108250/print-the-string-between-two-parentheses
Here is an example that is a lot of what I needed with my two directory levels, but aside from generally reminding me how to use awk I didn't end up stealing a lot of this: https://unix.stackexchange.com/questions/277231/how-to-get-second-directory-name-in-the-perforce-file-path
Here is the example that I stole most of my awk code from. It has several great examples, including using a for loop (which turned out to be largely unnecessary for me) and the kint of using the built-in swk variable FILENAME. https://unix.stackexchange.com/questions/134212/extract-file-name-from-path-in-awk-program
Here is where I got the other part of my awk code using the NF built in variable. The example is in a for loop but I was able to do the same thing with find and xargs: https://stackoverflow.com/questions/643372/append-name-of-parent-folders-and-subfolders-to-the-names-of-the-multiple-files
Here is an example of a super fancy xargs command with find: https://stackoverflow.com/questions/10972002/batch-renaming-files-in-command-line-and-xargs
Here is an example where somebody was just not doing xargs correctly, and the answers eventually converge on just using the -exec feature of find: https://unix.stackexchange.com/questions/90886/how-can-i-find-files-and-then-use-xargs-to-move-them
Here is another example of a for loop for somebody that is trying to do something remarkably similar to what I want to do, but these examples weren't actually very helpful: https://superuser.com/questions/516082/add-folder-name-to-beginning-of-filename