3

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.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Paincakes
  • 33
  • 1
  • 3

1 Answers1

5
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).

Kusalananda
  • 333,661
  • 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