1

I am writing a Python script to find and remove all .py files having corresponding .pyc files. How to extract this file list and remove them?

For example : consider there some file in /foo/bar:

file.py
file.pyc
file3.py
file2.py
file2.pyc...etc

I want to delete file.py,file2.py and not file3.py as it do not have corresponding .pyc file. and I want to do in all folders under '/'.

Is there one-liner bash code for the same?

P.S : I am using CentOS 6.8, having python2.7

2
  • Interesting request. Are you sure you don't want to delete .pyc files that have corresponding .py files? :) Commented Jan 6, 2017 at 4:44
  • No, it is a client request Commented Jan 6, 2017 at 4:47

4 Answers 4

2

Here's my solution:

    import os
    ab=[]
    for roots,dirs,files in os.walk("/home/foo/bar/"):
        for file in files:
            if file.endswith(".py"):
                ab.append(os.path.join(roots,file))
    bc=[]
    for i in range(len(ab)):
        bc.append(ab[i]+"c")
    xy=[]
    for roots,dirs,files in os.walk("/home/foo/bar/"):
        for file in files:
            if file.endswith(".pyc"):
                xy.append(os.path.join(roots,file))
    ex=[x[:-1] for x in bc if x in xy]
    for i in ex:
        os.remove(i)

P.S: Newbie in python scriptiing.

Sign up to request clarification or add additional context in comments.

Comments

1

Bash solution:

#!/bin/bash

find  /foo/bar -name "*.py" -exec ls  {} \;  > file1.txt
find  /foo/bar/ -name "*.pyc" -exec ls {} \; > file2.txt
p=`wc -l file1.txt| cut -d' ' -f1`
for ((c=1;c<=$p;c++))
do
  grep `sed -n ${c}p file1.txt | sed s/$/c/g` file2.txt > /dev/null
  if [ $? -eq 0 ]
     then
       list=`sed -n ${c}p file1.txt`
           echo " exist : $list"
           rm -rf `sed -n ${c}p file1.txt`
  fi
 done

Comments

0

this is a very operating-system-near solution

maybe make a shell script from the following commands and invoke it from python using subprocess.call (How to call a shell script from python code?, Calling an external command in Python)

find . -name "*.pyc" > /tmp/pyc.txt

find . -name "*.py" > /tmp/py.txt

from the entries of these files remove path and file ending using sed or basename:

for f in $(cat /tmp/pyc.txt) ; do sed 's/.*\///' remove path sed 's/\.[^.]*$//' remove file ending done

for f in $(cat /tmp/py.txt) ; do sed 's/.*\///' remove path sed 's/\.[^.]*$//' remove file ending done

(https://unix.stackexchange.com/questions/44735/how-to-get-only-filename-using-sed)

awk 'FNR==NR{a[$1];next}($1 in a){print}' /tmp/pyc.txt /tmp/py.txt > /tmp/rm.txt (https://unix.stackexchange.com/questions/125155/compare-two-files-for-matching-lines-and-store-positive-results)

for f in $(cat /tmp/rm.txt) ; do rm $f done (Unix: How to delete files listed in a file)

1 Comment

If possible I need one-liner code for the same?
0

The following code will work for a single layer directory. (Note: I wasn't sure how you wanted to handle multiple layers of folders --- e.g. if you have A.py in one folder and A.pyc in another, does it count as having both present, or do they have to be in the same layer of the same folder? If the latter case, it should be fairly simple to just loop through the folders and just call this code within each loop.)

import os

# Produces a sorted list of all files in a directory
dirList = os.listdir(folder_path)   # Use os.listdir() if want current directory
dirList.sort()

# Takes advantage of fact that both py and pyc files will share same name and
# that pyc files will appear immediately after their py counterparts in dirList

lastPyName = ""

for file in dirList:
    if file[-3:] == ".py":
        lastPyName = file[:-3]
    elif file[-4:] == ".pyc":
        if lastPyName == file[:-4]:
            os.remove(lastPyName + ".py")
            os.remove(lastPyName + ".pyc") # In case you want to delete this too

3 Comments

code works fine. But sometimes in dirlist .pyc file comes first then .py, For example: list[1]=argu.py list[2]=test1.pyc list[3]=self.py . . . list[10]=test.py will it cause any issue while comparing?
Try adding a sort after dirlist. E.g. dirlist = sort(dirlist) That should ensure that .pyc comes directly after its corresponding .py file.
To be clear, the python sorting syntax is dirList.sort(). I've added it to my code above.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.