I need to read a file where the content is like below :
Computer Location = afp.local/EANG
Description = RED_TXT
Device Name = EANG04W
Domain Name = afp.local
Full Name = Admintech
Hardware Monitoring Type = ASIC2
Last Blocked Application Scan Date = 1420558125
Last Custom Definition Scan Date = 1348087114
Last Hardware Scan Date = 1420533869
Last Policy Sync Date = 1420533623
Last Software Scan Date = 1420533924
Last Update Scan Date = 1420558125
Last Vulnerability Scan Date = 1420558125
LDAP Location = **CN=EANG04W**,OU=EANG,DC=afp,DC=local
Login Name = ADMINTECH
Main Board OEM Name = Dell Inc.
Number of Files = 384091
Primary Owner = **CN= LOUHICHI anoir**,OU=EANG,DC=afp,DC=localenter code here
I need to replace CN=$value by CN=Compagny where $value is what is retrived after CN= and before ,.
Ok, so you really should have updated your question an not posted the code in a comment, because it's really hard to read. Here's what I think you intended:
$file = 'D:\sources\scripts\2.txt'
$content = Get-Content $file | foreach ($line in $content) {
if ($line.Contains('CN=')) {
$variable = $line.Split(',').Split('=')[2]
$variable1 = $variable -replace $variable, "Compagny"
} Set-Content -path $file
}
That deffinately has some syntax errors. The first line is great, you define the path. Then things go wrong... Your call to Get-Content is fine, that will get the contents of the file, and send them down the pipe.
You pipe that directly into a ForEach loop, but it's the wrong kind. What you really want there is a ForEach-Object loop (which can be confusing, because it can be shortened to just ForEach when used in a pipeline like this). The ForEach-Object loop does not declare an internal variable (such as ($line in $content)) and instead the scriptblock uses the automatic variable $_. So your loop needs to become something like:
Get-Content $file | ForEach { <do stuff> } | Set-Content
Next let's look inside that loop. You use an If statement to see if the line contains "CN=", understandable, and functional. If it does you then split the line on commas, and then again on equals, selecting the second record. Hm, you create an array of strings anytime you split one, and you have split a string twice, but only specify which record of the array you want to work with for the second split. That could be a problem. Anyway, you assign that substring to $variable, and proceed to replace that whole thing with "company" and store that output to $variable1. So there's a couple issues here. Once you split the string on the commas you have the following array of strings:
"LDAP Location = **CN=EANG04W**"
"OU=EANG"
"DC=afp"
"DC=local"
That's an array with 4 string objects. So then you try to split at least one of those (because you don't specify which one) on the equals sign. You now have an array with 4 array objects, where each of those has 2 string objects:
("LDAP Location", "**CN", "EANG04W**")
("OU", "EANG")
("DC","afp")
("DC","local")
You do specify the third record at this point (arrays in PowerShell start at record 0, so [2] specifies the third record). But you didn't specify which record in the first array so it's just going to throw errors. Let's say that you actually selected what you really wanted though, and I'm guessing that would be "EANG04W". (by the way, that would be $_.Split(",")[0].Split("=")[1]). You then assign that to $Variable, and proceed to replace all of it with "Company", so after PowerShell expands the variable it would look like this:
$variable1 = "EANG04W" -replace "EANG04W", "company"
Ok, you just successfully assigned "company" to a variable. And your If statement ends there. You never output anything from inside your If statement, so Set-Content has nothing to set. Also, it would set that nothing for each and every line that is piped to the ForEach statement, re-writing the file each time, but fortunately for you the script didn't work so it didn't erase your file. Plus, since you were trying to pipe to Set-Content, there was no output at the end of the pipeline, you have assigned absolutely nothing to $content.
So let's try and fix it, shall we? First line? Works great! No change. Now, we aren't saving anything in a variable, we just want to update a file's content, so there's no need to have $Content = there. We'll just move on then, shall we? We pipe the Get-Content into a ForEach loop, just like you tried to do. Once inside the ForEach loop, we're going to do things a bit differently though. The -replace method performs a RegEx match. We can use that to our advantage here. We will replace the text you are interested in for each line, and if it's not found, no replacement will be made, and pass each line on down the pipeline. That will look something like this for the inside of the ForEach:
$_ -replace "(<=CN\=).*?(?=,)", "Company"
The breakdown of that RegEx match can be seen here: https://regex101.com/r/gH6hP2/1
But, let's just say that it looks for text that has 'CN=' immediately before it, and goes up to the first comma following it. In your example, that includes the two trailing asterisks, but it doesn't touch the leading ones. Is that what you intended? That would make the last line of your example file:
Primary Owner = **CN=Company,OU=EANG,DC=afp,DC=localenter code here
Well, if that is as intended, then we have a winner. Now we close out the ForEach loop, and pipe the output to Set-Content and we're all set! Personally, I would highly suggest outputting to a new file, in case you need to reference the original file for some reason later, so that's what I'm going to do.
$file = 'D:\sources\scripts\2.txt'
$newfile = Join-Path (split-path $file) -ChildPath ('Updated-'+(split-path $file -Leaf))
Get-Content $file | ForEach{$_ -replace "(?<=CN\=).*?(?=,)", "Company"} | Set-Content $newfile
Ok, that's it. That code will produce D:\sources\scripts\Updated-2.txt with the following content:
Computer Location = afp.local/EANG
Description = RED_TXT
Device Name = EANG04W
Domain Name = afp.local
Full Name = Admintech
Hardware Monitoring Type = ASIC2
Last Blocked Application Scan Date = 1420558125
Last Custom Definition Scan Date = 1348087114
Last Hardware Scan Date = 1420533869
Last Policy Sync Date = 1420533623
Last Software Scan Date = 1420533924
Last Update Scan Date = 1420558125
Last Vulnerability Scan Date = 1420558125
LDAP Location = **CN=Company,OU=EANG,DC=afp,DC=local
Login Name = ADMINTECH
Main Board OEM Name = Dell Inc.
Number of Files = 384091
Primary Owner = **CN=Company,OU=EANG,DC=afp,DC=localenter code here
foreach old_cellname $old_cell_full_name {
echo $old_cellname >> origin.txt}
foreach origin $cell_origin {
echo $origin >> origin.txt}
foreach new_cellname $new_cell_full_name {
echo $new_cellname >> origin.txt}
Using the above code I am able to get the output in the origin.txt as old cell names followed by their origin numbers followed by the new cell names. But i want my output as rows ie old cell name its origin and new cell name. Is it possible to make these changes? Any help is highly appreciated.
If the lists are of the same length and match up sensibly, yes, of course. Just use a multi-list foreach:
foreach old $old_cell_full_name origin $cell_origin new $new_cell_full_name {
# echo isn't a standard Tcl command, but I guess this ought to work
echo "$old\t$origin\t$new" >> origin.txt
}
I assume tab-separated will do. It's pretty convenient since it lets you import the data into a spreadsheet easily. If you prefer commas, use , instead of \t.
i'm using zendframwork 2 , i implement the album exemple in the official documentation
http://framework.zend.com/manual/2.1/en/user-guide/overview.html#the-tutorial-application (so in my model folder i have Album.php and AlbumTable.php) and all works fine , i just want to make a small modification :
i want to have acces to the third element in album . in the index.phtml view (originally i have this code )
<?php foreach ($albums as $album) : ?>
<?php echo $this->escapeHtml($album->title);?>
<?php echo $this->escapeHtml($album->artist);?>
<?php endforeach; ?>
i tried things like
<?php echo $this->escapeHtml($album->title[3]);?>
<?php echo $this->escapeHtml($album[3]->title);?>
but i always get this error
( ! ) Fatal error: Cannot use object of type Auth\Model\Album as array in C:\wamp\www\zf2-album\module\Auth\view\auth\auth\index.phtml on line 14
any help please ?
thanks every one
Do you need ONLY the third one? Then write your Query to be more efficient ;) For all other cases, since you are working with a Zend\Db\ResultSet\ResultSet, which uses Iterator you have different options.
The first one would be to still iterate through the fieldset like
while ($albums->key() != 3) {
$albums->next();
}
$album = $albums->current();
The alternative would be to simply convert the ResultSet into an array
$myAlbums = $albums->toArray();
$album = $myAlbums[3];
Depending on how big your ResultSet is and how many entries you really need, either Solution may be faster for you. Guess you have to test that one ;)
I want to be able to have multiple forms of the same parameter like so:
param(
[string]$p or $path = "C:\",
[string]$f or $filter = "*.txt",
[switch]$o or $overwrite
)
but I'm not sure how to do this. Most times, you would only be able to choose one (e.g. only $p or only $path). Is it possible to use multiple names for the same variable/parameter?
Like this:
param(
[Alias('p')]
[string]$path = "C:\",
[Alias('f')]
[string]$filter = "*.txt",
[Alias('o')]
[switch]$overwrite
)
Note you can have multiple aliases too: [Alias('p','thepath')]
PowerShell partial parameter name matching may be what your looking for.
# test.ps1
param($path)
write-host $path
Calling .\test.ps1 with either .\test.ps1 -path "c:\windows" or .\test.ps1 -p "c:\windows" will both match, and populate, the $path parameter.
I'm building a Task in Symfony with Doctrine. I'm getting all the places to make a batch update to a particular field. This has to be done in two languages. I'm using setBaseQuery() to make the JOIN on the query with the language I want.
If I do the following in an action, it works without any problem. However, If I do it in a task; it doesn't work as expected. The task runs perfectly two times (one in english and the other in english too!).
Any ideas on what I have to do different on tasks?
thanks!
$languages = array('es' => 'Spanish', 'en' => 'English');
foreach($languages as $lang => $value) {
// get all the places
$q = Doctrine::getTable('Place')
->createQuery('p')
->leftJoin('p.Translation ptr')
->addWhere('ptr.lang = ?', $lang);
$treeObject = Doctrine::getTable('Place')->getTree();
$rootColumnName = $treeObject->getAttribute ( 'rootColumnName' );
$treeObject->setBaseQuery($q);
// all the continents
foreach ( $treeObject->fetchRoots() as $continent ) {
$this->log(date("Y-m-d H:i:s").' '.$lang.' Continent '.$continent->title);
..
}
}
To gain database access in your tasks you'll need to call the following in your execute() method before any other database calls:
$databaseManager = new sfDatabaseManager($this->configuration);
http://www.symfony-project.org/book/1_2/16-Application-Management-Tools#chapter_16_sub_custom_tasks_new_in_symfony_1_1
so the solution I've found is adding $model->Translation[$lang]->title. It's strange because the title should have been loaded through the setbasequery; but it seems not.
// all the continents
foreach ( $treeObject->fetchRoots() as $continent ) {
$this->log(date("Y-m-d H:i:s").' '.$lang.' Continent '.$continent->Translation[$lang]->title);
..
}
Update
I'm getting the translation but $continent->save() didn't save the changes in Spanish (however it's saving it in English). I had to do a manual query in Doctrine:
$con = Doctrine_Manager::getInstance()->connection();
...
$con->execute("update model_translation set field='".$field."' where id='".$model->id."' and lang='".$lang."'");
now everything works...