1

I'm reading the RegEx chapter in Classic Shell Scripting and types the example code.

Here is the command: which changes the path "/home/tolstoy" to "/home/lt".

$ echo /home/tolstoy | sed 's;\(/home\)/tolstoy/;\1/lt/;'
/home/lt

However, when I execute it on zsh on my laptop, the return is

/home/tolstoy

Is this command wrong? What is the correct command and why?

3

You are, in your regular expression, trying to match a / after the string tolstoy. This / is not there in the input, so the expression does not match.

Modified to include the / in the input:

$ echo /home/tolstoy/ | sed 's;\(/home\)/tolstoy/;\1/lt/;'
/home/lt/

Modified to not match a trailing /:

$ echo /home/tolstoy | sed 's;\(/home\)/tolstoy;\1/lt/;'
/home/lt/

Modified to properly find the parent directory of tolstoy (regardless of trailing / in the input) and to add lt to the end of that path:

$ printf '%s/lt\n' "$(dirname /home/tolstoy)" 
/home/lt

Or,

$ printf '%s\n' "$(dirname /home/tolstoy)/lt" 
/home/lt

In general, don't use line-oriented text editing tools on Unix pathnames. Doing so would disqualify the script or command you are writing from working properly with some (albeit uncommon but valid) pathnames containing newlines.

  • Strictly speaking "$(dirname -- "$file")" also has issues with newline characters (trailing ones in the dir name). – Stéphane Chazelas Jan 31 at 9:50
  • @StéphaneChazelas Due to the command substitution, yes. – Kusalananda Jan 31 at 9:59

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.