0

I have parent folder includes sub folders. In every sub folder I have folders as follow:

Parent_folder
folder1
  folder_01_PAP_515151
  folder_02_PAPA_554651
  folder_03_PAPX_541313
  folder_04_PAP_654123
folder2
  folder_20_PAP_413513
  folder_02_PAPD_521354
  folder_055_PAP_685413
  folder_100_PAP_132312
folder3
  folder_11_PAPE_5313351
  folder_32_PAP_3513131
  folder_53_PAP_3213321
  folder_84_PAP_3313213

..

I used the following command to list all the folders and sub folders that contain "PAP" and save it in a text file "list.txt"

find -type d -name "*_PAP_" > list.txt

The output was as follow:

  ./folder1/folder_01_PAP_515151
  ./folder1/folder_04_PAP_654123
  ./folder1/folder_20_PAP_413513
  ./folder2/folder_055_PAP_685413
  ./folder2/folder_100_PAP_132312
  ./folder3/folder_32_PAP_3513131
  ./folder3/folder_53_PAP_3213321
  ./folder3/folder_84_PAP_3313213

From this list, I want to create new folders and the names of these new folders must contain the parts "three digits_PAP" e.g "055_PAP", "32_PAP", "53_PAP", ... from the previous list. The list of new generated folders must be:

 01_PAP
 04_PAP
 20_PAP
 055_PAP
 100_PAP
 32_PAP
 53_PAP
 84_PAP
2

If you have a file (named list containing, the following, and you with to create a directory for each line name in file, where the directory name is just the part after ./folder?/folder_.

./folder1/folder_01_PAP_515151
./folder1/folder_04_PAP_654123
./folder2/folder_055_PAP_685413
./folder2/folder_100_PAP_132312
./folder3/folder_32_PAP_3513131
./folder3/folder_53_PAP_3213321
./folder3/folder_84_PAP_3313213

Then you can do.

cat list | sed -r -e 's~[.]/folder[0-9]+/folder_~~' | xargs -I{} mkdir -p «prefix»{}

  • I have made it so that folder numbers are one or more digits.
  • Leave «prefix» blank, unless you want a prefix.

If you wish to just rename the original folders/directories, keeping original content, then you can do:

Test with this one. Then remove the -n from rename, to do it for real.

find . -type d -name "*_PAP_" | rename -n 's~[.]/folder[0-9]+/folder_~~'

Note the search pattern is the same for rename as it is for sed. rename works on filenames, sed works on files or streams.

The options to sed:

  • -r use extended regular expressions (the dialect of regular expression to use).
  • -e The next arg is the expression (sed program).
  • 's~[.]/folder[0-9]+/folder_~~' the expression, quoted so that the shell does not interpret it.

The expression explained: s~[.]/folder[0-9]+/folder_~~

  • s do a search and replace
  • ~ the separator character it separates the expression into sections, you can use any character, but must use the same one each time. s~«search_for»~«replace_with»~«options» or using a different character s@«search_for»@«replace_with»@«options».
  • «search_for» a regular expression:
    • [.] a dot
    • /folder just what it says.
    • [0-9] a digit.
    • + one or more of the preceding atom (the digit) (so one or more digits).
    • /folder_ just what it says.
  • «replace_with» What to replace it with, in this case nothing.
  • «option» in this case note, others include i ignore case, g do it more that once (not just first string found).

The sed/rename language is very powerful, though complex. The main parts that you would use are s (as used here), and maybe next y, these are worth learning. You will also have to learn regular expressions (also used by grep, and other commands).

  • What error are you getting? – ctrl-alt-delor Jul 10 '16 at 21:23
  • Many thanks for all your help. this is great !!! I just noticed that you revised it. The command was missing " ' " before s – user88036 Jul 10 '16 at 21:23
  • By the way, When I add a path following mkdir -p . It is not creating the new folders in that path? – user88036 Jul 10 '16 at 21:25
  • 1
    The / at the front tells it to be in the root. If you start with ./ or just a then it does it in the present working directory. Or ../ will put it in the parent directory. See the rules for directories in Unix. – ctrl-alt-delor Jul 10 '16 at 21:50
  • 1
    AHH! did you do … | xargs mkdir -p a/b/x This will not work, it will create to directories a local one according to the pattern and ./a/b/x. See amendment to answer (the -I{} and the {}). – ctrl-alt-delor Jul 10 '16 at 21:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy