0

I have a website where I'm formatting sass (.scss) files with the sass-convert command. Its syntax is this:

$> sass-convert original.scss formatted.scss

Since I'm in a git repo, having a separate output file is completely superfluous. My next step would be mv formatted.scss original.scss. I would like to do something to avoid the second step. Something like

$> sass-convert original.scss %^&

Where %^& is some magic shell/bash syntax that does what I want it to.

Is there a way I can auto-replace the output file with the input file in a single line, using bash (or another shell) syntax?

My question is different from this question because iconv will create the output file first, which would make the input file then empty, so none of the solutions listed below will work. If you look at the answers of both of these questions, you will see that they are different. The answers for this question work for any command that does not immediately create the output file.

user394
  • 14,404
  • 21
  • 67
  • 93

3 Answers3

5

Unix programs may have an -i inplace switch (e.g. older version of sed do not, but most now do having stolen that flag from perl), check the man page for details. This will usually cause the program to write the output to a temporary file and then perform a rename(2) call to write the new output over the original name (this rename may possibly also destroy selinux contexts or other fancy ACL in the process, which may be a concern if you use those things).

Another solution to the write-to-tmp-file-and-rename(2) pattern is sponge from moreutils:

$ echo hi > file
$ tr h b < file | sponge file
$ cat file
bi
$ 
thrig
  • 34,938
1

Using Bash history operators:

sass-convert original.scss !#:$

!# designates the current line, :$ the last argument (so far).

This works with sass-convert; but for more general use, it’s worth noting that programs which truncate their output before they finish processing their input won’t work using this approach.

Stephen Kitt
  • 434,908
0

In tcsh or zsh in emacs mode (generally the default), you can type:

sass-convert original.scss Ctrl+Alt+_

Ctrl+Alt+_ copies the previous word (copy-prev-word widget).

Note that it copies the previous blank-delimited word, it doesn't understand quoting or anything like that (contrary to !#:$ csh-style history expansion).

Another approach (also works with bash and other readline-based shells) still in emacs mode:

sass-convert original.scssCtrl+WCtrl+Y Ctrl+Y

With zsh, you can also do:

(){sass-convert $1 $1} original.scss

With (t)csh/ksh/zsh/bash, using brace expansion:

sass-convert original.scss{,}