Jump to content

Match string in a CSV file with PHP & then check for adjacent cell value


UnluckyForSome

Recommended Posts

I have a CSV file with 2 columns,

|   Primary   |   Secondary   |
|Cats.txt     |Dogs.txt       |
|Silk.txt     |Cotton.txt     |
|Coke.txt     |Pepsi.txt      |

Col A has a list of PRIMARY files Col B has a list of SECONDARY files

Col B's names correspond directly to the cell adjacent in Col A.

I want to add a function where the script goes through a directory and if it finds a filename matching something in Col B (a secondary file), it evaluates if the filename in the adjacent Col A exists (a primary file).

If it does, I want it to delete the secondary file from the directory. If it doesn't, it can leave it alone (as If a primary file doesn't exist a secondary will have to do!)

So far I've only got:

<?php
$fileList = trim(shell_exec("ls -a -1"));
$fileArray = explode("\n", $fileList);

shell_exec('mkdir -p Removed');

foreach ($fileArray as $thisFile)

//// if ($thisFile) is found in column B of the CSV file AND a PRIMARY version exists matching the adjacent cell in column A, return {$fCheck} ///

if {$fCheck}
{
     echo "Match for current file found in CSV and primary version exists, removing\n";
     shell_exec("mv " . escapeshellarg($thisGame) . " Removed/");
     continue;
}

I have tried a few bits and pieces in place of my if in the middle there but I have left them all out for clarity. I think I need to use fgetcsv? Would anybody be able to help me out? Apologies for my lack of knowledge as I've only just started PHP coding!

Many thanks!

Link to comment
Share on other sites

Used to shell scripting, huh? PHP is a fully-fledged language, you know. It can do things like listing files in a directory (you don't need to use this one), and creating directories, and moving files. Making PHP go off into a shell for those things is rather silly.

You say it's a CSV file. Is it actually a CSV file, as in

Cats.txt,Dogs.txt
Silk.txt,Cotton.txt
Coke.txt,Pepsi.txt

or something else? Because if it's actually a CSV file then yes, you should be using something like fgetcsv to read lines. Then you can check if the primary file exists and delete the secondary file if it does (or you can move it).

Link to comment
Share on other sites

Hi requinix,

Many thanks for the reply - yeah, unfortunately the script I've inherited (it does other things as well but I've removed them for the purpose of my question) already did things in this manner, I might get around to converting it all another time but for now I want to keep things consistent.

Unfortunately I'm not really used to any type of scripting! ?

It is indeed a csv.

So to start, it would be something like?:

$file = fopen("file.csv","r");

But then i'm stumped as to how to use fgetcsv to match Col B with $thisFile ?

Link to comment
Share on other sites

Thanks. I've managed to get it looking like this:

if (file_exists('test.csv'))
	{
	$f = fopen("test.csv", "r");
	$result = false;
	$row = fgetcsv($f);
	if ($row[1] == $thisFile)
		{
		$primaryFile = $row[0];

		// Assumes file extension for primary file is the same as for secondary

		$ext = pathinfo($thisFile, PATHINFO_EXTENSION);
		$fCheck = trim(shell_exec("ls -1 " . escapeshellarg($primaryFile) . "." . escapeshellarg($ext) . " 2>/dev/null"));
		if ($fCheck)
			{
			echo "match for current file found in CSV and primary version exists, removing\n";
			shell_exec("mv " . escapeshellarg($thisFile) . " Removed/");
			continue;
			}
		  else
			{
			echo "match found on the CSV, however you don't appear to have the primary version - so has been kept.\n";
			continue;
			}
		}
	}

However it's only matching the 1st row. How do I get it to match every row, one by one?

EDIT: I think I need a "while" loop but I have no idea how to implement it!

Many thanks!

Link to comment
Share on other sites

12 minutes ago, requinix said:

Did you look at the example in the documentation or not?

 Yes I did, but it's hard to understand. I'm not much of a coder. I now have:

 

    if (file_exists('test.csv'))
    {

        $f = fopen("test.csv", "r");
        while ($row = fgetcsv($f))
        {
            if ($row[1] == $thisFileNoExtension)
            {
                $primaryFile = $row[0];

                $ext = pathinfo($thisFile, PATHINFO_EXTENSION);
                $fCheck = trim(shell_exec("ls -1 " . escapeshellarg($primaryFile) . "." . escapeshellarg($ext) . " 2>/dev/null"));
                if ($fCheck)
                {
                    echo "\033[00;33mmatch for current file found in CSV and primary version exists, removing\n";
                    shell_exec("mv " . escapeshellarg($thisFile) . " Removed/");
                    continue;
                }
                else
                {
                    echo "\033[00;33mmatch found on the CSV, however you don't appear to have the primary version so has been kept.\n";
                    continue;
                }

                break;
            }
        }
    }

    echo "SHOULD NOT BE ECHO'ing";

But it's leaking - it's echoing (at the bottom there) when it should be continuing onto the next file. I'm also unsure if I need the "break". Thanks for your continued help!

Link to comment
Share on other sites

Again - RTFM to find out what that break does to your code.

BTW - when you do an IF statement what do you want to happen when it evaluates to False?  That's what the Else condition is for and you should always write code to handle that condition.  Again - RTFM.

Link to comment
Share on other sites

Hi - have read the documentation but I can't work out why I am still seeing the echo at the bottom of the script. I've simplified the script down so it isolates my problem:

<?php
$gameList = trim(shell_exec("ls -a -1 -I . -I .. -I Removed"));
$gameArray = explode("\n", $gameList);

shell_exec('mkdir -p Removed');

echo "\033[01;32m\n\n<<<<<<<<<<Starting Scan>>>>>>>>>>\n\n";

// Do the magic for every file
foreach ($gameArray as $thisGame)
{
    // Ensure continue if already removed
    if (!$thisGame) continue;
    if (!file_exists($thisGame)) continue;

    // Manipulate names to look and play nice
    $niceName = trim(preg_replace('%[\(|\[].*%', '', $thisGame));
    $thisGameNoExtension = preg_replace('/\.' . preg_quote(pathinfo($thisGame, PATHINFO_EXTENSION) , '/') . '$/', '', $thisGame);

    // Let the user know what game is being evaluated
    echo "\033[00;35m{$thisGameNoExtension} ... ";

    $f = fopen("ManualRegionDupes.csv", "r");
    while ($row = fgetcsv($f))
    {
        if ($row[1] == $thisGameNoExtension)
        {
            $primaryFile = $row[0];

            $ext = pathinfo($thisGame, PATHINFO_EXTENSION);
            $fCheck = trim(shell_exec("ls -1 " . escapeshellarg($primaryFile) . "." . escapeshellarg($ext) . " 2>/dev/null"));
            if ($fCheck)
            {
                echo "\033[00;33mmatch for current file found in CSV and primary version exists, removing\n";
                shell_exec("mv " . escapeshellarg($thisGame) . " Removed/");
                continue;
            }
            else
            {
                echo "\033[00;33mmatch found on the Manual Region Dupes list, however you don't appear to have the primary version so has been kept.\n";
                continue;
            }

            break;
        }
    }
    fclose($f);

    echo "\033[01;32mScanned and kept\n";
}
echo "\033[01;32m\n<<<<<<<<<<Process Complete>>>>>>>>>>\n\n";

?>

The script now works, although I can't work out why I'm seeing the echo "Scanned and kept", straight after either of the echo's describing a match on CSV - surely the "continue" here should mean the script moves on to another filename in the list before the final "Scanned and kept" echo? Many thanks!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.