Reasoning process of deep seek

Table of Contents

Question

you are an expert of macos and bash, the output is empty by the following command line, what's wrong? how to fix it?

echo "expiration = 1738939379000"|sed -n 's/^expiration\s=\s([0-9]+)$/\1/p'

Reasoning process

Okay, let me try to figure out why the sed command isn't giving any output. The user ran the command:

echo "expiration = 1738939379000" | sed -n 's/^expiration\s=\s$/\1/p'

And got empty output. Hmm. Let me think step by step.

First, the input string is "expiration = 1738939379000". The sed command is trying to match a line starting with "expiration", followed by any whitespace, an equals sign, more whitespace, and then a number. It captures the number and replaces the entire line with just the number. The -n option suppresses automatic printing, and the /p flag at the end prints the line if a substitution was made.

But why isn't it working? Let me check the regular expression syntax. Oh wait, macOS uses BSD sed by default, which might have different syntax compared to GNU sed. In BSD sed, the + operator isn't supported. Instead, you need to use {1,} to mean one or more occurrences. Also, the \s might not be recognized as whitespace. BSD sed uses [[:space:]] instead of \s.

So the original regex uses \s* for whitespace, which might not work on BSD sed. Also, the + after [0-9] is probably causing an issue because BSD sed expects {+} instead. Let me verify that.

In BSD sed, the basic regular expressions (BRE) are used by default. In BRE, the + is treated as a literal unless escaped with . But to match one or more, you have to use {1,}. So [0-9]+ would not work; it should be [0-9]{1,}. Also, \s is a Perl-compatible regex shorthand for whitespace, which isn't available in BSD sed. So instead of \s, I should use [[:space:]] to match any whitespace characters.

So putting that together, the corrected sed command for macOS would be:

sed -n 's/^expiration[[:space:]]=[[:space:]]
[0−9]{1,}[0−9]{1,}$/\1/p'

Testing this, the [[:space:]]* should match any spaces or tabs around the equals sign. The [0-9]{1,} matches one or more digits. Let's also check the line anchors. The ^ and $ ensure that the entire line is matched, which is correct here.

So the original problem is that the user was using GNU sed syntax on BSD sed, which doesn't recognize \s or +. Replacing those with the appropriate BSD sed syntax should fix the issue. Alternatively, the user could install GNU sed via Homebrew (as gsed) and use that instead, but modifying the regex to use BSD-compatible syntax is the direct fix here.

Answer

The issue arises because macOS uses BSD sed, which has slightly different syntax compared to GNU sed. The problems in your command are:

  1. \s (whitespace shorthand)
    BSD sed does not support \s. Use [[:space:]] instead.

  2. \+ (one-or-more quantifier)
    BSD sed requires \{1,\} instead of \+ for "one or more" matches.

Here's the fixed command:

echo "expiration = 1738939379000" | sed -n 's/^expiration[[:space:]]*=[[:space:]]*\([0-9]\{1,\}\)$/\1/p'

Explanation:

  • [[:space:]]* replaces \s* to match any whitespace (including spaces/tabs).
  • [0-9]\{1,\} replaces [0-9]\+ to match one or more digits.
  • The rest of the command remains the same.

Alternative Solution:
Install GNU sed (via Homebrew: brew install gnu-sed), then use gsed with your original syntax:

echo "expiration = 1738939379000" | gsed -n 's/^expiration\s*=\s*\([0-9]\+\)$/\1/p'

Either approach will correctly extract the timestamp 1738939379000 from your input.

Comments |0|

Legend *) Required fields are marked
**) You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Category: 似水流年