Prepend “!” to the beginning of the first line of

2020-07-03 07:06发布

I have several files that I need to add a "!" to the beginning, just on the first line. I still need to keep the first line's content, just add a "!" as the first character.

Any help would be really appreciated.

Thanks!

Edit: The only thing I could figure out so far was to do the following:

$a = Get-Content 'hh_Regulars3.csv'
$b = '!'
Set-Content 'hh_Regulars3-new.csv' -value $b,$a

This just added the "!" to the top of the file, instead of to the beginning of the first line.

标签: powershell
4条回答
一夜七次
2楼-- · 2020-07-03 07:35

You sent an array to Set-Content with $b,$a. Each array item will be given its own line as you have seen. It would displayed the same way on the prompt if executed.

As long as the file is not too big read it in as one string and add the character in.

$path = 'hh_Regulars3.csv'
"!" + (Get-Content $path -Raw) | Set-Content $path

If you only have PowerShell 2.0 then Out-String would work in place of -Raw

"!" + (Get-Content $path | Out-String) | Set-Content $path

The brackets are important to be sure the file is read in before it goes to through the pipeline. It allows us to both read and write on the same pipeline.

If the file is larger look into using StreamReaders and StreamWriters. This would also have to be used if the trailing new line, created by the Add-Content and Set-Content, is not warranted.

查看更多
Rolldiameter
3楼-- · 2020-07-03 07:36

Late to the party, but thought this might be useful. I needed to perform the operation over a thousand+ large files, and needed something a little more robust and less prone to OOM exceptions. Ended up just writing it leveraging .Net libraries:

function PrependTo-File{
  [cmdletbinding()]
  param(
    [Parameter(
      Position=1,
      ValueFromPipeline=$true,
      Mandatory=$true,
      ValueFromPipelineByPropertyName=$true
    )]
    [System.IO.FileInfo]
    $file,
    [string]
    [Parameter(
      Position=0,
      ValueFromPipeline=$false,
      Mandatory=$true
    )]
    $content
  )

  process{
    if(!$file.exists){
      write-error "$file does not exist";
      return;
    }
    $filepath = $file.fullname;
    $tmptoken = (get-location).path + "\_tmpfile" + $file.name;
    write-verbose "$tmptoken created to as buffer";
    $tfs = [System.io.file]::create($tmptoken);
    $fs = [System.IO.File]::Open($file.fullname,[System.IO.FileMode]::Open,[System.IO.FileAccess]::ReadWrite);
    try{
      $msg = $content.tochararray();
      $tfs.write($msg,0,$msg.length);
      $fs.position = 0;
      $fs.copyTo($tfs);
    }
    catch{
      write-verbose $_.Exception.Message;
    }
    finally{

      $tfs.close();
      # close calls dispose and gc.supressfinalize internally
      $fs.close();
      if($error.count -eq 0){
        write-verbose ("updating $filepath");
        [System.io.File]::Delete($filepath);
        [System.io.file]::Move($tmptoken,$filepath);
      }
      else{
        $error.clear();
        write-verbose ("an error occured, rolling back. $filepath not effected");
        [System.io.file]::Delete($tmptoken);
      }
    }
  }
}

Usage:

PS> get-item fileName.ext | PrependTo-File "contentToAdd`r`n"
查看更多
Luminary・发光体
4楼-- · 2020-07-03 07:46

This oneliner might works :

get-ChildItem *.txt | % { [System.Collections.ArrayList]$lines=Get-Content $_;
                          $lines[0]=$lines[0].Insert(0,"!") ;
                          Set-Content "new_$($_.name)" -Value $lines}
查看更多
Melony?
5楼-- · 2020-07-03 07:54

Try this:

$a = get-content "c:\yourfile.csv"
$a | %{ $b = "!" + $a ; $b | add-content "c:\newfile.csv" }
查看更多
登录 后发表回答