Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: Moving Files Between Subdirectories

  1. #1
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Moving Files Between Subdirectories

    What am I missing here?
    What am I doing wrong?

    Code:
    find /home/wyatt/Desktop/Test-Folder/Test-Dir-1/* -type f '*.txt' -print0 | xargs -0 mv -t /home/wyatt/Desktop/Test-Folder/Test-Dir-2/TXT
    I ran the above command line and got the following...

    Code:
    find: paths must precede expression: `*.txt'
    mv: missing file operand
    Try 'mv --help' for more information.
    I've been working on this command for quite some time now.

    Avoiding the "current working directory", I'm wanting to move files within subdirectories into subdirectories within another desktop folder.
    I'm using a small test directory with copied files.

    I checked the manual's, it seem's they just cause me more confusion.
    I've checked all of the following links for commands and idea's.
    It seem's I "just can't get it through my thick head"

    https://unix.stackexchange.com/quest...-similar-names
    https://stackoverflow.com/questions/...d-on-extension
    https://askubuntu.com/questions/4438...ticular-string
    https://tecadmin.net/delete-files-older-x-days/
    https://stackoverflow.com/questions/...d-on-extension
    https://unix.stackexchange.com/quest...es-into-one-di
    https://unix.stackexchange.com/quest...-based-on?rq=1
    https://unix.stackexchange.com/quest...s-into-one-di#
    Last edited by wyattwhiteeagle; May 30th, 2023 at 08:47 AM.

  2. #2
    Join Date
    Dec 2014
    Beans
    2,594

    Re: Moving Files Between Subdirectories

    You're missing an option before '*.txt' - probably '-name' or '-iname'. Without that option find interprets '*.txt' as another path you want to search, but all paths need to come before tests or actions and therefore find gives an error and no results, therefore xargs has nothing to feed into mv and then mv produces an error because there are to few parameters - there need to be at least two.

    Holger

  3. #3
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Re: Moving Files Between Subdirectories

    Quote Originally Posted by Holger_Gehrke View Post
    You're missing an option before '*.txt' - probably '-name' or '-iname'. Without that option find interprets '*.txt' as another path you want to search, but all paths need to come before tests or actions and therefore find gives an error and no results, therefore xargs has nothing to feed into mv and then mv produces an error because there are to few parameters - there need to be at least two.

    Holger

    Thank you
    Adding -name into the mix did the trick...
    Code:
    find /home/wyatt/Desktop/Test-Folder/Test-Dir-1/* -type f -name '*.txt' -print0 | xargs -0 mv -t /home/wyatt/Desktop/Test-Folder/Test-Dir-2/TXT

    There's times when I get the "will not overwrite" message.


    Where in that command line would '--backup=numbered' best fit?

  4. #4
    Join Date
    Dec 2014
    Beans
    2,594

    Re: Moving Files Between Subdirectories

    Anywhere after mv is good but not in between '-t' and the path.

    By the way, the difference between -name and -iname is case sensitivity, so if there are '*.TXT' flies in there you want to move then '-iname' is the better choice.

    Holger

  5. #5
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Re: Moving Files Between Subdirectories

    Quote Originally Posted by Holger_Gehrke View Post
    Anywhere after mv is good but not in between '-t' and the path.

    By the way, the difference between -name and -iname is case sensitivity, so if there are '*.TXT' flies in there you want to move then '-iname' is the better choice.

    Holger
    Thank you

    I'll "tweak" the command and let ya know how it goes.

  6. #6
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Re: Moving Files Between Subdirectories

    Code:
    find /home/wyatt/Desktop/Test-Folder/Test-Dir-1/* -type f -iname '*.txt' -print0 | xargs -0 mv --backup=numbered -t /home/wyatt/Desktop/Test-Folder/Test-Dir-2/TXT

    That worked.
    Is there a way to have it put the number before the '.txt'?

  7. #7
    Join Date
    Dec 2014
    Beans
    2,594

    Re: Moving Files Between Subdirectories

    Not with the 'mv' command itself. But you can run a rename afterwards:
    Code:
    rename 's/txt\.~(.*)~$/~$1~.txt/i' *
    The part in single quotes is a Perl expression; the 's' means substitute, the slashes are separators, the part between the first and second slash is the text to search for, the part between the second and third slash is the replacement, and the trailing 'i' is an option meaning 'case insensitiv'. The "text to search for" is a regular expression; most characters in RE stand for themselves, the exceptions (in this one) are '.' (which stands for one arbitrary character), '\' (takes away any special meaning from the following character, so '\.' means a literal '.' and not an arbitrary character, '*' (a quantifier meaning as many of the previous character as can be found; '.*' means as many (including 0) arbitrary characters as there are), '$' (meaning 'end of input'), and the parentheses are for grouping sub-expressions and remembering them (so the sub-expression can be used in the replacement; '"$1", "$2", "$3" ... stand for the first, second, third sub-expression in parentheses.

    Holger

  8. #8
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Re: Moving Files Between Subdirectories

    Quote Originally Posted by Holger_Gehrke View Post
    Not with the 'mv' command itself. But you can run a rename afterwards:
    Code:
    rename 's/txt\.~(.*)~$/~$1~.txt/i' *
    The part in single quotes is a Perl expression; the 's' means substitute, the slashes are separators, the part between the first and second slash is the text to search for, the part between the second and third slash is the replacement, and the trailing 'i' is an option meaning 'case insensitiv'. The "text to search for" is a regular expression; most characters in RE stand for themselves, the exceptions (in this one) are '.' (which stands for one arbitrary character), '\' (takes away any special meaning from the following character, so '\.' means a literal '.' and not an arbitrary character, '*' (a quantifier meaning as many of the previous character as can be found; '.*' means as many (including 0) arbitrary characters as there are), '$' (meaning 'end of input'), and the parentheses are for grouping sub-expressions and remembering them (so the sub-expression can be used in the replacement; '"$1", "$2", "$3" ... stand for the first, second, third sub-expression in parentheses.

    Holger
    Is that for the "current working directory" only?
    Is it for one file only, thus repeating the line for each file to rename?

  9. #9
    Join Date
    Dec 2014
    Beans
    2,594

    Re: Moving Files Between Subdirectories

    The way it's written it's for all files in the current directory. That's what the '*' at the end of the command means; you could instead give an exact filename or a list of filenames or a glob that matches specific files; only files which match the RE will be renamed, so using '*' is safe if the expression is specific enough. I wouldn't be surprised at all if there was some really tricky and smart way to make rename recurse through a directory hierarchy using only a very clever RE, but if there is one I don't know it.

    You could of course use 'find' again to recurse through all directories
    Code:
    find . -type d -print -execdir bash -c 'rename -n '\''s/txt\.~(.*)~$/~$1~.txt/i'\'' *' \;
    The '-print' is in there to get some feedback on where find currently is; the '-n' makes rename just print out what it would do (it prints "rename(<oldname>,<newname>)" for each file it would rename) - it's basically a 'dry-run' to check that it doesn't do anything horrible. I strongly advise letting this dry-run happen, since I don't have any numbered backup-files lying around in a deep hierarchy and couldn't really test this. After you're sure everything works as intended, do a second run without the '-n' in the rename-command.

    Calling bash through '-execdir' is necessary to make the glob / wildcard '*' work right; globs are processed by the shell after you hit enter but before execution of the command starts by turning them into a list of filenames matching the glob. If you wrote "find . -type d -print -execdir rename -n 's/txt\.~(.*)~$/~$1~.txt/i' * \;' instead, the '*' would get replaced with a list of files by the shell after you hit enter so rename would try to rename the filenames from the starting directory in each subdirectory; if you escaped the '*' with a backslash or by having it in single quotes to stop the shell from expanding the glob, then rename wouldn't know what to do with the '*' since it expects the shell to handle wildcards. It would probably look for a file named literally '*' and fail.

    Holger
    Last edited by Holger_Gehrke; May 30th, 2023 at 09:06 PM.

  10. #10
    Join Date
    Aug 2014
    Beans
    523
    Distro
    Lubuntu 22.04 Jammy Jellyfish

    Re: Moving Files Between Subdirectories

    Will you please explain how a "dry-run" of this nature works?

    I know how a simulated install works.
    Is a command dry-run similar, or are there differences?

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •