0

I want to replace a specific occurence of the word "Metal" in a number of .mac-files. As far as I saw these are text files.

First example file:

Size : 24mm 1547856 Metal
Colour : red
Number : 1547856 Metal

Second example file:

Size : 26mm 2658915 Metal
Colour : blue
Number : 2658915 Metal

I want to replace Number : 1547856 Metal with Number : 1547856 Steel in the first file and Number : 2658915 Metal with Number : 2658915 Steel in the second file, but I don't want the "Metal" in the first line to be replaced.

I tried doing it with the the following code via Terminal, but it replaces all occurences of "Metal" in the files:

maccmd /replace "Metal" "Steel" 

How can I replace only the "Metal" in the line that starts with "Number" without replacing any other occurence of "Metal" in the file?

I don't know anything about the maccmd program. So I am fine with a simple windows batch program.

Julia
  • 21
  • 2
  • Wouldn't it be easier to use a native shell and be able to use sed and awk? – lit Jun 12 '18 at 12:36
  • Thanks Max Vollmer thats very friendly! – Julia Jun 12 '18 at 13:42
  • You might want to look into regular expressions. I can't post a full answer right now, but if that `/replace` command allows regular expressions, it should be fairly easy. [This](https://stackoverflow.com/questions/11392478/how-to-replace-a-string-in-multiple-files-in-linux-command-line) might help. – Max Vollmer Jun 12 '18 at 13:51
  • @MaxVollmer I need this for the windows terminal, because I have .mac-files on a windows pc.I can not install a unix shell – Julia Jun 12 '18 at 15:37
  • @aschipfl I only have windows terminal – Julia Jun 12 '18 at 15:39
  • Ah, okay, sorry for the misunderstanding! – Max Vollmer Jun 12 '18 at 16:50

2 Answers2

1

found a solution with PowerShell, but it is only working for text files.

$find="world"
$replace="nice"
$path="path to folder"
$position=0

Get-ChildItem $path -Filter * | 
Foreach-Object {
    $file = $_.FullName

    $string=Get-Content $file -Raw
    $pos=$string.IndexOf($find, $string.IndexOf($find)+$position)


  if ($pos -ne -1)
  {
      "{0}{1}{2}" -f $string.Substring(0, $pos), $replace, $string.Substring($pos + $find.Length) | Out-File -filepath $file 
  } else {
     $string | Out-File -filepath $file 
  }

}
Julia
  • 21
  • 2
  • This program only works for text files. When I try to do it with my .mac files, I can't open afterwards. Does anyone have a idea what I can try to do to handle it with .mac files? – Julia Jun 13 '18 at 07:05
  • 1
    What is a `.mac` file? I guess it is a text file using a particular encoding and/or line-break style, so please tell us... – aschipfl Jun 13 '18 at 12:35
0

The following (let us call it replac.bat) works only if the text file does not contain ||, if DOS-/Windows- or Unix-style line-breaks (CR + LF or LF, respectively) are used and if the encoding is ASCII-/ANSI-text:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=%~1"    & rem // (file to process; use first command line argument)
set "_FIND=Number" & rem // (string at beginning of lines to find lines to process)
set "_SRCH=Metal"  & rem // (string at end of lines to be replaced)
set "_REPL=Steel"  & rem // (string to replace found string at end of lines)

for /F "delims=" %%L in ('findstr /N "^" "%_FILE%"') do (
    for /F "tokens=1-2 delims=: " %%I in ("%%L") do (
        set "LINE=%%L" & set "ITEM=%%J"
        setlocal EnableDelayedExpansion
        set "EXCH=!LINE!||" & set "EXCH=!EXCH:%_SRCH%||=%_REPL%||!" & set "EXCH=!EXCH:||=!"
        if "!ITEM!"=="%_FIND%" (
            echo(!EXCH:*:=!
        ) else (
            echo(!LINE:*:=!
        )
        endlocal
    )
)

endlocal
exit /B

The text file (let us assume sample.txt) must be given as a command line argument, like this:

replac.bat "sample.txt"

To write the output to a different file (let us assume return.txt) use redirection, like this:

replac.bat "sample.txt" > "return.txt"
aschipfl
  • 33,626
  • 12
  • 54
  • 99