Efstathios Efrintidis
Efstathios Efrintidis

Reputation: 27

CMD script: Reading and saving the last word of each line (multiple lines)

My question is about finding and saving the last word of each line.

I have multiple lines. This information is saved in a .txt file. Thus, I am required to build a CMD script that can scan through the txt file, find the last word of each line and save it to a new .txt document. The delimiters here will be the space.

For example:

It's a very small window<34>.
The small birds were singing softly.
There are three small rooms up stairs (4)
The house has but two small second story bedrooms.

The result I would like to see saved in a separate txt document needs to look like the following:

window<34>.
softly.
(4)
bedrooms.

I have tried many options and methods but unfortunately no luck.

Upvotes: 1

Views: 1008

Answers (3)

Aacini
Aacini

Reputation: 67216

This pure Batch method correctly process all characters, but it is limited in the number of words per line (26 in this version), although such a limit may be increased via the usual tricks.

@echo off
setlocal DisableDelayedExpansion

for /F tokens^=1-26^ eol^= %%a in (input.txt) do (
   set "last="
   for %%T in (z y x w v u t s r q p o n m l k j i h g f e d c b a) do (
      if not defined last call :sub %%T
   )
)
goto :EOF

:sub token
for %%? in (-) do (
   set "last=%%%1"
   if defined last echo %%%1
)
exit /B

Upvotes: 2

dbenham
dbenham

Reputation: 130819

Squashman's answer can fail if the file contains quotes and poison characters.

It is possible to write a pure batch solution that reliably does the job, regardless of content.

@echo off
setlocal disableDelayedExpansion
>"output.txt" (
  for /f usebackq^ delims^=^ eol^= %%A in ("input.txt") do (
    set "s=%%A"
    setlocal enableDelayedExpansion
    set "s=!s:@=@a!"
    set "s=!s:\=@b!"
    set "s=!s:/=@f!"
    set "s=!s:.=@d!"
    set "s=!s: =.!"
    for /f "delims=" %%A in (".!s!") do (
      endlocal
      set "s=%%~xA"
      setlocal enableDelayedExpansion
      if defined s (
        set "s=!s:.= !"
        set "s=!s:@d=.!"
        set "s=!s:@f=/!"
        set "s=!s:@b=\!"
        set "s=!s:@a=@!"
        echo(!s:~1!
      )
      endlocal
    )
  )
)

But I would never use a pure batch solution. Instead I would use JREPL.BAT - a hybrid batch/Jscript utility that efficiently performs regular expression search and replace on text. It isn't pure batch, but it is pure script that runs natively on any Windows machine from XP onward - no 3rd party .exe file required.

call jrepl "(\S+)\s*$" "$txt=$1" /jmatchq /f input.txt /o output.txt

One nice thing about both solutions is that they give the correct result even if there are spaces after the last "word". And they don't print anything if the line does not contain any "word"

Upvotes: 1

Squashman
Squashman

Reputation: 14290

Give this a try. It uses a neat trick with the SET command. You can get a high level overview of this technique at dostips.com.

@echo off & setlocal enableextensions disabledelayedexpansion

FOR /F "delims=" %%G IN (test.txt) DO CALL :lasttoken "%%~G"
GOTO :EOF

:lasttoken
set "x=%~1"
set "x1=%x: =" & set "x2=%"
setlocal enabledelayedexpansion
>>newtest.txt echo !x2!
endlocal
goto :eof

Upvotes: 2

Related Questions