Hot answers tagged

57

An alternative very lightweight option is just to 'tail' everything but the first line (this can be an easy way to remove file headers generally): # -n +2 : start at line 2 of the file. tail -n +2 file.txt > file.stdout Following @Evan Teitelman, you can: tail -n +2 file.txt | sponge file.txt To avoid a temporary file. Another option might be: ...


45

The single bracket [ is actually an alias for the test command, it's not syntax. One of the downsides (of many) of the single bracket is that if one or more of the operands it is trying to evaluate return an empty string, it will complain that it was expecting two operands (binary). This is why you see people do [ x$foo = x$blah ], the x guarantees that ...


38

Maybe not what you're asking for, but this should work to some extent to identify the interpreter currently interpreting it for a few like Thomson (osh), Bourne, Bourne-again, Korn, Z, (T)C, Policy-compliant Ordinary, Yet Another, rc, akanga, es shells, wish, tclsh, expect, perl, python, ruby, php, JavaScript (SpiderMonkey shell and JSPL at least), MS/Wine ...


38

The reason file.txt is empty after that command is the order in which the shell does things. The first thing that happens with that line is the redirection. The file "file.txt" is opened and truncated to 0 bytes. After that the sed command runs, but at the point the file is already empty. There are a few options, most involve writing to a temporary file. ...


37

Brace expansion is very useful if you have long path names. I use it as a quick way to backup a file: cp /a/really/long/path/to/some/file.txt{,.bak} will copy /a/really/long/path/to/some/file.txt to /a/really/long/path/to/some/file.txt.bak You can also use it in a sequence. I once did so to download lots of pages from the web: wget ...


28

It is not possible to give a real answer to this question, but the form of a comment is not sufficient. So I think it may be a good idea to collect points to a editable answer... Two years ago, David and Glenn have been layed off by AT&T - I guess both are now over 65. Half a year later, they have been hired by Google and Glenn confirmed me that their ...


27

When they are not quoted, $* and $@ are the same. You shouldn't use either of these, because they can break unexpectedly as soon as you have arguments containing spaces or wildcards. "$*" expands to a single word "$1c$2c...". Usually c is a space, but it's actually the first character of IFS, so it can be anything you choose. The only good use I've ...


25

The [ command is an ordinary command. Although most shells provide it as a built-in for efficiency, it obeys the shell's normal syntactic rules. [ is exactly equivalent to test, except that [ requires a ] as its last argument and test doesn't. The double brackets [[ … ]] are special syntax. They were introduced in ksh (several years after [) because [ can ...


24

This is used for alias protection: $ ls .bashrc a b $ alias ls alias ls='ls $LS_OPTIONS' $ \ls a b


22

You can set set the TMOUT variable to a number in seconds that you wish for bash to wait before automatically logging out the shell if no command is run.


21

Brace expansion comes very handy when creating large directory structures: mkdir -p dir1/{subdir1,subdir2}/{subsubdir1,subsubdir2} This will give you find dir1 -type d dir1 dir1/subdir1 dir1/subdir1/subsubdir1 dir1/subdir1/subsubdir2 dir1/subdir2 dir1/subdir2/subsubdir1 dir1/subdir2/subsubdir2 You could even go one step further and put brace expansion ...


20

I usually use the -exec utility. Like this: find . -type f -exec du -a {} + I tried it both on bash and ksh with GNU find. I never tried AIX, but I'm sure your version of find has some -exec syntax. The following snippet sorts the list, largest first: find . -type f -exec du -a {} + | sort -n -r | less


18

{ cat sample1.txt; tail -n +4 sample2.txt; tail -n +4 sample3.txt; } > out.txt


18

Using find is still the preferred way of deleting files. See http://mywiki.wooledge.org/UsingFind for more. One way of doing this is to create a file with the time-stamp in it. e.g touch -t 201311220000 /tmp/timestamp Now delete the files GNUfind (assuming in the current directory) that match the time-stamp e.g: find . -type f ! -newer /tmp/timestamp ...


17

I use it when I want to reduce typing: geany /path/to/file1 /path/to/file2 # versus geany /path/to/file{1,2} Another example: wajig install libpam0g-dev libiw-dev libdb-dev # versus wajig install lib{pam0g,iw,db}-dev


16

First of all, you should use straight single quotes ('), not the inclined ones (`). The awk inline script could be as follow: ls -lrt | awk '{ total += $5 }; END { print total }' so, no need to initialize total (awk initializes it to zero), and no need to loop, awk already executes the script on every line of input.


16

Short answer: use "$@" (note the double quotes). The other forms are very rarely useful. "$@" is a rather strange syntax. It is replaced by all the positional parameters, as separate fields. If there are no positional parameters ($# is 0), then "$@" expands to nothing (not an empty string, but a list with 0 elements), if there is one positional parameter ...


16

When "SOMEPATTERN" starts or may start (for instance if it's a variable like "$PATTERN" which you don't have full control on) with a - (dash) character. Also with GNU grep (unless $POSIXLY_CORRECT is on), it's useful if other arguments (file names) may start with -. Alternatively, you can do grep -e -SOMEPATTERN- -- file1 file2 -xxx- -- marks the end of ...


16

For the sake of variety, here's another way with cut: cut -d \; -f -3


15

A function is local to a shell, so you'd need find -exec to spawn a shell and have that function defined in that shell before being able to use it. Something like: find ... -exec ksh -c ' function foo { echo blan: "$@" } foo "$@"' ksh {} + bash allows one to export functions via the environment with export -f, so you can do (in bash): foo() { ...


15

Here is a simple script to demonstrates the different between $* and $@: #!/bin/bash test_param() { echo "Receive $# parameters" echo Using '$*' echo for param in $*; do printf '==>%s<==\n' "$param" done; echo echo Using '"$*"' for param in "$*"; do printf '==>%s<==\n' "$param" done; echo echo Using '$@' for ...


15

It's showing the contents of the special variable $@, in Bash. It contains all the command line arguments, and this command is taking all the arguments from the second one on and storing them in a variable, variable. Example Here's an exampe script. #!/bin/bash echo ${@:2} variable=${@:3} echo $variable Example run: ./ex.bash 1 2 3 4 5 2 3 4 5 3 4 5 ...


15

At least for bash the man page defines the export syntax as: export [-fn] [name[=word]] ... It also defines a "name" as: name A word consisting only of alphanumeric characters and under‐ scores, and beginning with an alphabetic character or an under‐ score. Also referred to as an identifier. Hence you really cannot define ...


15

On linux you can use /proc/PID/exe. Example: # readlink /proc/$$/exe /bin/zsh


14

@enzotib has already pointed out what your syntax error is - I'm going to go off on a little tangent. Summing a column of numbers is one of those things that keeps popping up. I've ended up with this shell function: sumcol() { awk "{sum+=\$$1} END {print sum}" } With this, your solution becomes: ls -lrt | sumcol 5 That will sum the numbers in ...


13

From help let: Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.. Since var++ is post-increment, I guess the last argument does evaluate to zero. Subtle... A perhaps clearer illustration: $ let x=-1 ; echo x=$x \$?=$? x=-1 $?=0 $ let x=0 ; echo x=$x \$?=$? x=0 $?=1 $ let x=1 ; echo x=$x \$?=$? x=1 $?=0 $ let x=2 ; echo ...


12

AProgrammer's suggestion of using xargs is often best, but another option is to use redirection into a while loop, which allows additional commands to be made and variables to be set: while read -r dir; do mkdir $dir; done < myfile An example of a more complicated structure would be: now=`date +%Y%m%d.%H%M%S` while read -r dir; do ...


11

I'd do something like xargs mkdir < myfile


11

You can do this sort of thing with eval, built-in to many fine shells, including ksh: #!/usr/bin/ksh set $(iostat) myvar=6 eval "echo \$$myvar" The trick is to double-quote the string you feed to eval so that $myvar gets substituted with "6", and to backslash the outer dollar-sign, so that eval gets a string "$6". I got "%user" for the output, but I ...


11

You should reduce the columns output by ps to the minimum, i.e. request only the username here - this simplifies further processing. For example: $ ps -eo user= will print the owner of all the currently running processes (= suppresses the header). An easy way to get the counts for each user: $ ps -eo user= | sort | uniq -c 1 dovecot 1 messagebus ...



Only top voted, non community-wiki answers of a minimum length are eligible