简体   繁体   中英

filter files with find command, sort output into directories

#!/bin/env bash

MONTHS=(Jan Feb Mar ...)

for month in ${MONTHS[@]}
do
    if [ ! -d $month ]; then
        mkdir $month
    fi

    # below is the code I would like to improve upon
    find ./ -iname "*$month*.pdf" -type f | xargs mv $month/
done

What I was trying to do, was:

1) Using the variable MONTHS , loop through each iteration by first checking if a directory with such a name exists, and if it doesn't, make a directory with the name (so when month=Jan , if Jan directory doesn't exist, it would make a Jan directory. if it does exist, proceed to next line, etc).

2) Find files in the current directory that has the month variable in its name (so it looks for all files with the word Jan in the file name, Feb , Mar , etc).

3) Pipe the output by moving it to the directory with the same month variable name (so all Jan files get moved to the Jan directory, Feb files into the Feb directory, etc).

I've been trying to code the last find command line for quite awhile, I checked most of the questions that are relevant however the most I've gotten was an error saying I cant move fileThatHasMonthInTheName.pdf into its own subdirectory sameLongFilename or that it's trying to move the month folder into itself.

My goal is to: find files that have the month name in the filename, pipe it to the directory who has the same month name


Command that produced the output by @thanasisp

find . -maxdepth 1 -type f -name "*$month*" | xargs -I{} mv {} $month

you could make these modifications

MONTHS=( Jan Feb Mar )

for month in ${MONTHS[@]}
do
    mkdir -p $month
    find . -maxdepth 1 -type f -name "*$month*" | xargs -I{} mv {} $month
done
  • mkdir -p will create the dir if not exists

  • find files should be restricted to maxdepth 1 so that won't return files previously copied to existing month dirs

  • use xargs with -I in order to process the find output in right position, preserving any arguments with spaces, eg a file named Jan 01.csv

As the other answer explains, find does recurse into sub-directories. My solution is simply to use ls, which does not (it will only show files in the current directory):

#!/bin/bash

MONTHS=(Jan Feb Mar ...)

for month in ${MONTHS[@]}
do
    if [ ! -d $month ]; then
        mkdir $month
    fi
    /bin/ls *$month*.pdf | xargs mv -t $month
done

I use /bin/ls to make sure I do not carry any alias formatting that some users prefer into the script.

NOTE: I edited the ls command to include the missing *. It is now /bin/ls *$month*.pdf like the OP wanted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM