Find the answer to your Linux question:
Results 1 to 7 of 7
Hi everyone I need a command line script that can change all (there are 8 folders perhaps i could apply each of them)folder contents files such as 10001.DAT 10002.DAT 10003.DAT ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Nov 2004
    Location
    middle Asia
    Posts
    81

    file name change under linux bash


    Hi everyone
    I need a command line script that can change all (there are 8 folders perhaps i could apply each of them)folder contents files such as 10001.DAT 10002.DAT 10003.DAT 10004.DAT to 10001.mp3 10002.mp3 10003.mp3

    Thanks.

  2. #2
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    648
    within each directory do:
    Code:
    for fn in *.DAT; do mv ${fn} ${fn%DAT}mp3; done

  3. #3
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,558
    Quote Originally Posted by alf55 View Post
    within each directory do:
    Code:
    for fn in *.DAT; do mv ${fn} ${fn%DAT}mp3; done
    You might also want to check out the rename command, and use that with find.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  4. #4
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Slackware, {Free, Open, Net}BSD, Solaris
    Posts
    1,288
    Hi.

    You might be able to avoid find by making use of the shell filename expansion facility. The perl substitution-expressions are not trivial, but for this case are fairly straight-forward. Here are before-and-after situations for several files in 2 directories:
    Code:
    #!/usr/bin/env bash
    
    # @(#) s1	Demonstrate renaming files with perl-expressions, rename.
    
    # Utility functions: print-as-echo, print-line-with-visual-space, debug.
    # export PATH="/usr/local/bin:/usr/bin:/bin"
    pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
    pl() { pe;pe "-----" ;pe "$*"; }
    db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
    db() { : ; }
    C=$HOME/bin/context && [ -f $C ] && $C tree rename
    
    # Create and list directories.
    ./create
    
    pl " Directories and files:"
    tree
    
    pl " Results, renaming, expecting message:"
    rename 's/\.DAT$/.mp3/' d1/* d2/*.DAT
    tree
    
    exit 0
    prodcuing:
    Code:
    % ./s1
    
    Environment: LC_ALL = C, LANG = C
    (Versions displayed with local utility "version")
    OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
    Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
    GNU bash 3.2.39
    tree v1.5.2 (c) 1996 - 2008 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro 
    rename - ( /usr/bin/rename, 2009-05-27 )
    
    -----
     Directories and files:
    .
    |-- create
    |-- d1
    |   |-- 10001.DAT
    |   |-- 10002.DAT
    |   |-- 10003.DAT
    |   |-- 99.DATA
    |   `-- xxDAT
    |-- d2
    |   |-- 10001.DAT
    |   |-- 10002.DAT
    |   |-- 10009.DAT
    |   `-- 10009.mp3
    |-- readme.txt
    `-- s1
    
    2 directories, 12 files
    
    -----
     Results, renaming, expecting message:
    d2/10009.DAT not renamed: d2/10009.mp3 already exists
    .
    |-- create
    |-- d1
    |   |-- 10001.mp3
    |   |-- 10002.mp3
    |   |-- 10003.mp3
    |   |-- 99.DATA
    |   `-- xxDAT
    |-- d2
    |   |-- 10001.mp3
    |   |-- 10002.mp3
    |   |-- 10009.DAT
    |   `-- 10009.mp3
    |-- readme.txt
    `-- s1
    
    2 directories, 12 files
    The two filename expressions on the rename command show that one can simply ask for all filenames to be looked at, or one can be more specific.

    There is a limitation on the length of commands, and so the rename command might become too long, in which case, separate invocations of rename could be used, or find may need to be used as noted by Rubberman. A find-xarg combination is often used to balance large numbers of files with efficiency, but one can begin simply and move on to more complex solutions as circumstances demand.

    See man rename for details, especially option "--no-act" to allow you to see what would be done. Backups are always useful when experimenting with new commands ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  5. #5
    Just Joined!
    Join Date
    Nov 2004
    Location
    middle Asia
    Posts
    81
    Thanks all of u.

    One more question
    Is it possible to add this directory names to this new mp3 files?

    - New Files
    --10002.DAT
    --10003.DAT
    --10004.DAT

    New_Files_10001.mp3
    New_Files_10002.mp3
    New_Files_10003.mp3

    Old Files
    Old_Files_10001.mp3
    Old_Files_10002.mp3

    like that ?

  6. #6
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Try this script out. It will look for all files ending in ".DAT" (case-insensitive) in the current working dir and will recurse into subdirectories, too.

    It will first print what it is going to do (move file.dat file.mp3) but i've commented out the actual command that does the move. run it as is, to see if it works right (does it determine the mp3 filename correctly, etc.). If it does look okay, then uncomment the line with the mv command (should be line 20 or so).

    you'll notice that all the magic that changes the name from "New File/10001.DAT" to "New_File_10001.mp3" is in the sed command around line 16. See if you can figure out what it is doing (hint: there are 4 separate sed commands in there, semicolon-delimited).
    Code:
    #!/bin/bash
    
    # modify the Input Field Separator (to handle file/dir names with spaces)
    OIFS=$IFS
    IFS='
    '
    
    # run a recursive find to look for DAT files in the current working dir
    dats=($(find . -type f -iname '*.dat' 2>/dev/null))
    echo "Found [${#dats[*]}] DAT files"
    
    # loop thru all DAT files found
    for dat in ${dats[*]}; do
    
      # get mp3 file name
      mp3=$(echo "$dat"|sed -e 's|^\./||;s|/|_|g;s| |_|g;s|\.dat$|.mp3|gi')
    
      # move the DAT file to the new mp3 filename
      printf "Moving $dat to $mp3 ... "
    #  out=$(mv -v $dat $mp3 2>&1)
      if [ $? -eq 0 ]; then
        echo OK
      else
        echo FAILED
        printf "$out\n"
        exit 1
      fi
    
    done
    IFS=$OIFS

  7. #7
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    648
    The command "mv" is move or rename. In some distros (fedora for one) tends to add "rename" as an alias. If you use Linux, the proper commands should be used as you may not stay with a distro for years or decades.

    I stay away from using find when not needed as it might change files that were not in the selection list. To do a set of directories the above command can be run inside another for loop.
    Code:
    for d in directory_01 directory_02 directory_03 directory_04; do
        for fn in *.DAT; do mv ${fn} ${fn%DAT}mp3; done
    done

Posting Permissions

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