Tag Archives: unix

The simple solution with awk is doing:

awk ‘{print $NF}’

This is useful when like in the following  we want to list just files skipping directories:

ls -l | awk ‘NR!=1 && !/^d/ {print $NF}

There are other options of course, take a look at this example from a nice collection of bash and unix tips

 

 

This is more of quick reminder for myself on the difficult task of escaping quotes and running an awk or sed command inside the bash command line. I solved the issue in my case using the octal representation of a single quote (\47), taken from here, where more options are shown.

Having previously accommodated the list of stale links with their replacements in a two columns format that looked like:

http://addressOld.com http://www.goodWorkingOne.com
http://addressOld2.com http://www.goodWorkingOne2.com
etc…

I used the following:

awk '{print "UPDATE library SET url=\47"$2"\47 WHERE url=\47"$1"\47;"}' 

to correctly generated what I wanted sql-postgres statements to update the links table:

UPDATE links SET url='http://goodWorkingOne.com' WHERE url='http://addressOld.com';

Using an interactive shell in Emacs for Windows you might enconter a bug that causes the shell process to terminate when you signal and eof (See point 7.6 here)
If, for example, you try:

/Program Files/Emacs/ cat >newfile
this is a test file
being created with the cat command
directly from the user input 
in shell.

Now, by pressing C-d (or C-c C-d) the input should finish here, and the prompt return, but what happens instead, is that the shell process terminates. Same thing occurs if you try to M-x comint-send-eof or if you pick an eof signal from the menu.

I had noticed that before (in my Windows emac, only not under Unix), but last night I found that an eof sign could be generated by typing C-q C-z.

I choose to set an alias and bind it to some keys in my .emacs to overcome the issue:

(defalias 'eof
  (read-kbd-macro "C-q C-z RET"))
(global-set-key [M-S-f8] 'eof)

Of course a better solution would be to advice the comint-send-eof to procede accordingly when in emacs for Windows. Anybody knows how to do it, or mind to share a stronger fix than this hack? Any feedback will be appreciated.

Update:
Actually there’s no need to set an alias, as I learned that this is also possible and more straight-forward:

(global-set-key [(meta shift f8)]
 '(lambda () (interactive) (execute-kbd-macro((read-kbd-macro "C-q C-z RET")))))

On how to delete a chunk of text contained in multiple lines: use sed to catch the range (/a/,/b/)

There were some javascript google ads calls from a page I downloaded via wget, doing:

 wget www.someSite.com/somePage.html > toCleanItUp.htlm

After highlighting all the page C-x h I did a M-x shell-command-on-region and used the following:

sed "/<script .*>/,/<\/script>/d" > nowItIsClean.html

If feeling lazy, (or if I don’t have the file opened already in an emacs buffer), there’s the straightforward way of using cat:

cat toCleanItUp.html | sed "/<script .*>/,/<\/script>/d" > nowItIsClean.html

Ah, the beauty of unix tools!

This one was eluding me for a while, what I simple wanted is to use cp (copy) with xargs to duplicate files in a different destination. What I had used before is the command copy in combination with find, via the exec argument like this:

find . -maxdepth 1 -name 'in*.css' -exec cp '{}' ~/src/Report/geo_portal/t/tmpl/src/css/ \;

But I wanted to use xargs, since I pretty much like its elegance and possibilites. The example below is a real one I used in BSD 7:

find . -name '*.html' | xargs grep -l 'Datasets' | xargs -J % cp -rp % ~/src/Report/playground/t/tmpl/src/css/

The explanation lies in the xargs manual, albeit a bit obscure. Here it goes:

-J replstr
If this option is specified, xargs will use the data read from standard input to replace the first occurrence of replstr instead of appending that data after all other arguments. This option will not affect how many arguments will be read from input (-n), or the size of the command(s) xargs will generate (-s). The option just moves where those arguments will be placed in the command(s) that are executed. The replstr must show up as a distinct argument to xargs. It will not be recognized if, for instance, it is in the middle of a quoted string. Furthermore, only the first occurrence of the replstr will be replaced. For example, the following command will copy the list of files and directories which start with an uppercase letter in the current directory to destdir:

/bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir

Note: When I wanted to use it in my Cygwin shell I had to replace the option “-J” with “-I”. In this example I copied every image lighter that 3000k into other folder.

ls -ltra | awk '{print $5," ",$9}' | awk '$1 < 3000' | awk '/gif|png|jpg/ {print $2}' | xargs -I % cp -rp % /web/R/images/

Here’s something interesting I just learned about. You can echo a command to see it’s syntaxis before running it in the command line, and then, pipe it to the shell, like this:

echo ls -ltra | awk '/.html~/' | xargs rm

(examine it carefully) and call it again adding ” bash

echo ls -ltra | awk '/.html~/'| xargs rm | bash

Another recent use I gave to it is in this command:

svn status | grep ^M | awk '{print "scp ",$2," me@xxx:/home/myTemp/"}' | tr -d '\n' | bash

Which: 1) pulls the status from the svn, 2)filters the modified files, 3) prints the scp command with the name of the file and the destination, 4) makes that a sequence in one line (by removing the newlines “\n”), and finally pipes all to bash to execute all the commands and get the modified files moved elsewhere.

find . -type f -mtime -22 | awk '/gif/' | cut -c 3- | awk '{print "scp ",$0, " me@xxx:/home/ignacio/myTemp"}' | bash -i

This last example doesn’t need the (\n) newlines removed to run thanks to the “-i” option after bash
Ain’t it sweet?

To massively replace text from a group of files:
// this searches all html files (not into htdocs) which contain tab = “DATs” and modifies that to tab = “Datasets” in one pass
// it’s important to notice that in the process they leave a backup copy of each one with the -e appended to the extension so bla.html will be modified but an extra bla.htm-e will exist holding the content of the old file

find .  -name '*.html' | awk '!/htdocs/' | xargs grep -l 'tab = "DATs"' | xargs sed -i -e 's/tab = "DATs"/tab = "Datasets"/g'

Note1: Actually the -i option takes whatever it’s after to create the extension of the backup to create. Use -ei if you want nothing or -e -i.bak to make it more standard.
Note2:
this worked better later on

find . -type f | xargs grep "url *=> *'/DAT_introduction.html'" | awk '!/svn|htdocs|blib|README|.bk/' | awk '{print $1}' | awk -F ':' '{print $1}' | xargs perl -pi -e "s#url *=> *'/DAT_introduction.html'#url => '/datasets.html'#g"

There are many things different:
awk cleans clean up the fields so to have only the path and file name printed
awk also helps here filtering out many option I don’t want to list and they are put together with the simple clause “|” (or) in the regex

instead of sed I used perl this time (sort of more familiar), notice that I used a different character “#” for the substitution delimiter, since I don’t want to escape “/” in the regex