2

I have the following file from which I want to extract only Removed '2022-01-30_01-00-05', at the end.

Removing '2022-01-30_01-00-05'...
  0.46% complete (00:03:45 remaining)^M  5.49% complete (00:00:17 remaining)^M 24.90% complete (00:00:06 remaining)^M 60.56% complete (00:00:01 remaining)^M 82.12% complete (00:00:00 remaining)^M 82.39% complete (00:00:01 remaining)^M 84.24% complete (00:00:01 remaining)^M 86.48% complete (00:00:01 remaining)^M 88.58% complete (00:00:01 remaining)^M 89.66% complete (00:00:01 remaining)^M101.08% complete (00:00:00 remaining)^M104.62% complete (00:00:00 remaining)^M                                                                                ^MRemoved '2022-01-30_01-00-05'

I've tried dos2unix but it didn't work.

I've tried these variations, below, but when I less output they either don't remove the ^M characters, or the whole line is captured:

tr -d $'\r' < /file | grep "Removed" > output
tr -d '^M' < /file | grep "Removed" > output
tr -d ^M < /file | grep "Removed" > output
sed 's/\r//g' < /file | grep "Removed" > output
0

4 Answers 4

5

The grep command will print the entire matching line and since lines in *nix are defined by \n and not \r, what you describe is normal behavior. In other words, your first and last commands (the tr -d '\r' and the sed 's/\r//g') are both working as intended, it's just that grep is doing what it's supposed to do and printing the entire line.

To only print part of a line, you need GNU grep and its -o option. For example:

$ grep -oP "Removed\s*'[^']+'" file
Removed '2022-01-30_01-00-05'

Alternatively, change the \r (the ^M) to newline characters instead of deleting them:

$ tr '\r' '\n' < file | grep Removed
Removed '2022-01-30_01-00-05'

Or

$ sed 's/\r/\n/g' file | grep Removed
Removed '2022-01-30_01-00-05'
1
  • Also tr '\r' '\n' <file | tail -n 1, or tail -n 1 file | sed 's/.*\r//'.
    – they
    Feb 6 at 7:14
5

dos2unix strips control-Ms (\r) from immediately before the end of lines (\n) - that's not what you have, you have control-Ms instead of end of lines. Hence dos2unix not helping you.

With GNU awk for multi-chars RS and using any sequence of \rs and/or \ns as the record separators:

$ awk -v RS='[\r\n]+' '/^Removed/' file
Removed '2022-01-30_01-00-05'
0
awk '{for(i=1;i<=NF;i++){if($i ~ /Removed/){print $i,$(i+1)}}}' filename| awk '{gsub(/\^M/,"",$0);print }'

output

Removed '2022-01-30_01-00-05'
0

Your input file has Mac line breaks. You can convert them to Unix line breaks with

dos2unix -c mac file

or

mac2unix file

To find out which type of line breaks your file has you can use this command:

dos2unix -ih file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.