Tag Info

Hot answers tagged

13

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 ...


12

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. ...


10

That's a ksh feature also found in bash and recent versions of zsh. In ksh and bash, you can access several elements of an array by using the ${array[@]:first:length} syntax, which expands to up to length (or all if length is omitted) elements of the array array (in the list of elements of the array sorted numerically on the indexes), starting with the ...


7

You should use it this way: ls -l | awk -v d="$Date" '$0 ~ d {print $NF}' Explanation is here But may be it's better to use find in your script. find . -maxdepth 1 -type f -daystart -ctime -`date "+%d"` If you have classic awk instead of gawk: find * -prune -type f -cmin -`date '+%d %H %M' | awk '{print ($1*24+$2)*60+$3}'`


7

The LINE parameter isn't quoted so wordsplitting happens upon the expansion of $LINE in echo $LINE and by the time awk receives any input, you have 7 words(as seen by the shell) all separated by a single space. You want echo to output it as one word(again, as seen by the shell) so the whitespace in your line isn't mangled before awk can process it. That is ...


7

With awk: awk '{ print $(NF-1) }' NF is the number of fields -- all that happens here is that one is subtracted from the total field length to get the penultimate field. With perl: perl -lane 'print $F[-2]' An array containing the fields is created as @F (that's what -a does), and we get the value of the second last field (with index -2). Using sed ...


6

All you need is join join -t\, <(sort Output1.csv) <(sort Output2.csv) -or- join -t "," <(sort Output1.csv) <(sort Output2.csv) or awk awk -F, 'FNR==NR{a[$1]=$2;next}{ print $0 "," a[$1]}' Output2.csv Output1.csv


6

ksh 93 has a nameref command that let's you create "aliases" to variables: var1EMI=a var2EMI=b for v in var1 var2; do nameref var=${v}EMI echo "${v}EMI is $var" done var1EMI is a var2EMI is b For ksh88, you may be forced to use eval: replace nameref var=${v}EMI with eval var=\$${v}EMI


6

With GNU sort and GNU du (which it appears you have, since you state you are using du's -h option): du -sh -- * | sort -rh # Files and directories, or du -sh -- */ | sort -rh # Directories only The output looks something like this: 22G foo/ 21G bar/ 5.4G baz/ 2.1G qux/ 1021M wibble/ 4.0K wobble/


5

Reproduced from the comp.unix.shell FAQ (since CFAJ's site seems to be down at the moment and I happen to have written that section of the FAQ): How do I get the exit code of cmd1 in cmd1|cmd2 First, note that cmd1 exit code could be non-zero and still don't mean an error. This happens for instance in cmd | head -n 1 you might observe a 141 (or 269 with ...


5

If you do the following: ls | grep -F -v ' ' You will not see any file with spaces in the names ( I used to have fgrep instead of grep -F in the example, but as Hauke Laging pointed out that is deprecated)


5

Not a ksh expert but I think you have two problems in your code. First problem: You have to single quote M$9001 otherwise the shell will try to expand $9001. Second problem: You do not nest [ ] inside [ ]. Either use [[ ]] or two [ ]. You should also quote $H_OR_T just in case it expands to something funny. Here is your code probably fixed: if [[ ...


5

If you were on Linux, you could simply use: date -d @1381260225 Or you could use awk: echo "1381260225" | awk '{print strftime("%c",$1)}' Or Python: python -c "import datetime; print datetime.datetime.fromtimestamp(1381865497)" Or Perl: perl -e 'print(scalar(localtime(1381865497)), "\n";' However none of these solutions are available on a stock ...


5

You're checking if the file exists by using -f, but that's not what you want to do. The file exists in the tar file, but -f has no way of reading inside tar archives by itself. For example, if your file is at "foo/bar" inside the tar file, it will look for "foo/bar" relative your current directory, which doesn't exist. The better way is to just check the ...


5

If you're sure that end_time is always greater than start_time, you can use Perl like so: export start_time=06:07:25 export end_time=07:02:08 perl -e ' ($h1,$m1,$s1) = split /:/,$ENV{start_time}; ($h2,$m2,$s2) = split /:/,$ENV{end_time}; $delta_h = $h2 - $h1; $delta_m = $m2 - $m1; if( $delta_m < 0 ) { $delta_m = $delta_h-- * 60 + $m2 ...


5

There are 2 redirects there. The last bit, 2>&1 is actually merging STDERR in with STDOUT. This looks to me like someone set this up to log output to the doit.log file but then wanted to disable it. Chaining redirects in this manner, basically negates the earlier ones, so that only the output, if there is any, will get directed to the last redirected ...


5

You could put the read and your case in a while loop and break out of it when the condition is satisfied: while : ; do echo "yes or no?" read ans case $ans in [yY]*) echo "yes" break ;; [nN]*) echo "no" break ;; *) echo "yes or no only" ;; esac done The while : ; do ... ...


4

As discussed in the comments, the problem is where you've left the cursor. For example: goldilocks@home> echo -n 1234; echo -ne "\r56" 56goldilocks@home> What happened is the first echo wrote "1234", then the second echo went back to the beginning of the line and printed "56" and exited. The cursor remained after the 6, and the next thing that ...


4

left=$(tput cub1) right=$(tput cuf1) printf %5s1; printf '%s\n' "$left${left}2${right}3" Details From the Bash Prompt HOWTO: tput cub1 move left one space tput cuf1 non-destructive space (move right one space)


4

Your format assumes that no file names have newlines in them, which is not ideal (newlines are legal in filenames). You also don't mention your shell. However, in a POSIX shell, you can do this: while IFS= read -r file; do cp -- "$file" new_dir/ done < file In bash, it might be faster to pass them all to cp in one go, however (as long as you're ...


4

If you want to redirect the STDOUT and STDERR to /dev/null for xset -q, you should do: xset -q > /dev/null 2>&1 || { echo "The Display Server is BROKEN. Aborting."; exit 1; } The redirection of using &> only works within bash or zsh. Therefore you should use 2>&1 to let redirection work in all Bourne-like shells.


4

You can also use grep: grep "91_987986787688899.*successful" file Unless your file has a very strange format, you could also probably just do this: awk '/91_987986787688899.*successful/' file There is no need for print $0, it is implied.


4

Use eval: filemsgCICS=foo word1=CICS eval "echo \"\$filemsg$word1\"" # => foo eval "filemsg$word1=bar" echo "$filemsgCICS" # => bar but think twice if you really need it this way. Another way in ksh93 is to use namerefs: word1=CICS nameref v=filemsg$word1 v="xxx" echo "$filemsgCICS" # => xxx For even more nasty hacks like that look here.


4

Like Lawrence has mentioned, you can use cp -v to enable "verbose" mode, which displays the files you copy. Something else that might be useful is cp -v > foo which will output the list of files to a file called foo. This is useful if you're going to copy a lot of files and you want to be able to review the list later.


4

There are 3 main implementations of ksh the original one from David Korn (AT&T ksh), with two main branches: ksh88 and ksh93 (and for ksh93, many version with new features added for each). pdksh, the public domain version (a free reimplementation of ksh88 with which it is mostly compatible) which is the base upon which is built the sh on some BSDs like ...


4

Assuming all the filenames in the current directory follow that pattern, with GNU ls: ls -rv | awk -F_ '++n[$1]>2' | xargs rm You can omit the | xargs rm if you want to check what it would remove first. That assumes the part in {...} doesn't contain space, newline, single quote, double quote, backslash, tab or underscore characters. The key is the -v ...


3

for f in *; do regular="${f#*-}" echo "$f => $regular" done This parameter expansion (${f#*-}) removes, from the start of the variable's value, the shortest string that ends with a hyphen (see manual). So: $ f=32456113-summary-report.doc $ echo "$f => ${f#*-}" 32456113-summary-report.doc => summary-report.doc


3

I usually need to make use of the resize and reset commands to sometimes clear/fix problems when resizing the actual xterm window. To use resize: $ eval `resize` If you run resize by itself, it'll report what the columns & lines will be set to. To use reset: $ reset References reset man page resize man page


3

(Inspired by Gilles's answer) With the ISIG flag set, the only way for the Child script to get SIGINT without its parent getting SIGINT is for it to be in its own process group. This can be accomplished with the set -m option. If you turn on the -m option in the Child shell script, it will perform job control without being interactive. This will cause it ...


3

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 ...



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