2

I am having problems trying to create a script to rename all of the files in my directory to .txt on Linux.

This is what I have so far.

#!/bin/bash

location_number=$(find /hw1/textarchive | wc -l)
org_path=/hw1/textarchive/!(*txt)
count=0

#for count in $location_number
#do
    # rename $org_path .txt 
    #rename $org_path *.txt
    # mv $org_path  $org_path.txt
#done

for count in $location_path
do
    rename $org_path .pro .txt *.pro  <-----was trying to just rename .pro to .txt (no luck)
done

echo done

I tried using mv and rename but I got nowhere. With the mv $org_path $org_path.txt when I run that I would get an error along the lines of (this file) is not a directory. With rename it would run without any error, but it would not rename any files to .txt.

2
  • Please remember to always mention your operating system and, if Linux, the distribution. There are many different rename commands and each works a little differently.
    – terdon
    Sep 15 '17 at 14:06
  • @terdon OK got it. Sorry about that. I am using Windows and connecting to my school Linux via an SSH.
    – Paincakes
    Sep 15 '17 at 14:15
3
for name in /hw1/textarchive/*.pro; do
    newname=${name%.pro}.txt
    echo mv "$name" "$newname"
done

or shorter,

for name in /hw1/textarchive/*.pro; do
    echo mv "$name" "${name%.pro}.txt"
done

(remove the echo when you are certain it's doing the right thing)

This iterates over all the .pro files under /hw1/textarchive and renames them to .txt files. The ${name%.pro} substitution will remove the .pro extension from the end of the name in $name.


If you want to rename all files:

for name in /hw1/textarchive/*; do
    echo mv "$name" "${name%.*}.txt"
done

The ${name%.*} will remove any extension at the end of the name. Existing .txt files will also be processed, but will not have their names changed. Files without extension will get a new .txt extension. This will also pick up names of non-files (like directories), so the following alteration will skip these:

for name in /hw1/textarchive/*; do
    test -f "$name" || continue
    echo mv "$name" "${name%.*}.txt"
done

It may be prudent to make sure there's not already a directory entry with the new name too:

for name in /hw1/textarchive/*; do
    test -f "$name" || continue
    test -e "${name%.*}.txt" && continue
    echo mv "$name" "${name%.*}.txt"
done

On another equivalent form:

for name in /hw1/textarchive/*; do
    if [ -f "$name" ] && [ ! -e "${name%.*}.txt" ]; then
        echo mv "$name" "${name%.*}.txt"
    fi
done

The -f test tests for the existence of the given regular file. The -e test tests for the existence of the given name (no matter what it is a name of).

This solution does not require bash (just an sh-compatible shell).

2
  • Thx for the info. Two questions 1) in your case do I have to declare name as a variable for it to work in the for loop. 2) how would I go about in "adding" .txt to files that do not have any extensions?
    – Paincakes
    Sep 15 '17 at 13:45
  • @Paincakes 1) no. 2) see update
    – Kusalananda
    Sep 15 '17 at 13:46

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.