Tag Info

Hot answers tagged

21

You need to use ;& instead of ;; to get a fall-through behavior: #! /bin/bash foo() { case "$1" in 3) echo "Level Three" ;& 2) echo "Level Two" ;& 1) echo "Level One" ;; a) echo "Level a" ;& b) ...


8

When w's output goes to a terminal. w queries the terminal driver for the number of columns and adjusts the width accordingly. When output doesn't go to a terminal such as when it goes to a pipe, it reverts to a fixed width of 80 columns. Versions of procps since 3.3.2 allow to override that default with the $COLUMNS environment variable. Some shells like ...


7

In many shells including ksh, zsh and bash, time is a keyword and is used to time pipelines. time foo | bar Will time both the foo and bar commands (zsh will show you the breakdown). It reports it on the shell's stderr. time foo.sh > bar.txt Will tell you the time needed to open bar.txt and run foo.sh. If you want to redirect time's output, you ...


6

Under Linux try man 7 signal. kill -HUP 1234 means "send the SIGHUP signal (1) to process 1234", so it's equivalent to kill -1 1234. The default signal that is sent by kill is SIGTERM (15), so kill 1234 is equivalent to kill -TERM 1234 or kill -15 1234.


6

You're confusing arguments and standard input. Piping data to a program is not equivalent to giving it command line arguments. In your first case, you are passing no arguments to your script, only feeding it data through its standard input stream. So $1 is unset for the whole duration of the script. The first invocation of more thus has no parameter, and ...


6

Most likely one of your $FOO variables contains special characters that are interpreted by sed. I have another version of sed which generates other error messages but here is an example of a similar problem: $ VAR=a $ echo i | sed -e "s/i/"$VAR"/" a $ tmp> VAR=/ $ echo i | sed -e "s/i/"$VAR"/" sed: 1: "s/i/// ": bad flag in substitute command: '/' In ...


6

As tagged bash, here is a bash 4.0 alternative to choroba's answer, to avoid wc and sed: bash-4.2$ mapfile -t a < file bash-4.2$ (IFS='+'; echo "(${a[*]})/${#a[@]}") | bc -l 1.24886080000000000000


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

It's a POSIX shell variable substitution feature : ${var%Pattern} Remove from $var the shortest part of $Pattern that matches the back end of $var. ${var%%Pattern} Remove from $var the longest part of $Pattern that matches the back end of $var. So if var="abc def ghi jkl" echo "${var% *}" # will echo "abc def ghi" echo "${var%% *}" # will echo "abc"


4

alias my_du=$'while printf \'%s \' "$(df -P / | awk \'NR==2 { print $(NF-1) }\')"; do sleep 3; done' You can check the result with alias my_du If $() is quoted by " instead of ' or \ then it is substituted and the result rather than the intended program call becomes part of the alias definition.


4

You can't escape single quotes whilst still in single quotes because \ is taken literally in a single quote context. Either close the single quotes before escaping, or, better, use double quotes. alias my_du="while printf '%s ' \"\$(df -P / | awk 'NR==2 { print \$(NF-1) }')\"; do sleep 30; done"


4

One trick that mostly works (for perl, python, php interpreters, and probably others): #!/usr/bin/env expect I think env is always in /usr/bin/. A lot of interpreters can run that way now. Other hacks used to exist, but weren't understandable, or weren't all that portable.


4

-HUP isn't the three flags H, U, P as in the common single-letter option syntax. For historical reasons, the kill command takes an optional signal name or signal number preceded by a dash (-). kill -1 1234 kill -HUP 1234 (As opposed to kill 1 1234, which would send the default signal (SIGTERM) to processes 1 and 1234.) Your man page probably lists ...


4

The difference is in "Arguments" VS "Standard Input". When you run echo dir1 | bash script.sh, the $1 argument in your script.sh is always empty as no argument is given to it (try adding a set -x at the begin and you will see it in the debug output). The dir1 which is echoed comes from standard input as the more command read stdin if no argument is given ...


4

As mentioned, use other separator or escape the slashes. Your last try misses escape of last slash. And as pointed out by @StephaneChazelas, escape dot's as well. And, including @terdon if sed is not needed; grep -Fxv, where -F is fixed string, not regex, would be an option. -x makes sure it matches whole lines. -v inverts. A simple (very simple) ...


4

You can change the here-doc operator to <<-. You can then indent both the here-doc and the delimiter with tabs: #! /bin/bash cat <<-EOF indented EOF echo Done Note that you must use tabs, not spaces to indent the here-doc. There can not be any quotes around the first EOF delimiter, else parameter expansion, command substitution, and ...


4

For reference, in zsh, you can affect the order globs are expanded with the o globbing qualifier. For instance *.mp3(om) sorts by modification time. You can define your own sorting order with functions. With *.mp3(o+foo), the files are sorted, not based on their name but on the value that the foo function returns in the $REPLY variable for a given filename ...


3

sed -ne '/^These/{n;w tempfile d;};p' < oldfile > newfile echo "These switches don't have latest images :" >> newfile cat tempfile >> newfile One could use the hold space instead of a temporary file: sed -ne '/^These/{n;H;d;};p;${x;s/^/These switches don'"'"'t have latest images :/;p;}' < oldfile > newfile This will fail, ...


3

Odds are that the 2 scripts are in different directories. One of the directories is on the PATH while the other is not. You can use the type command to test if a file is present on your current shell's $PATH. $ type start_dropbox.bash start_dropbox.bash is /home/saml/bin/start_dropbox.bash See this U&L Q&A "How do I test to see if an application ...


3

While this can be coaxed into an alias, functions are generally preferred. From man bash: For almost every purpose, aliases are superseded by shell functions. Your alias in function form: my_du() { while printf '%s ' "$(df -P / | awk 'NR==2 { print $(NF-1) }')" do sleep 30 done } That's more readable, and as such more ...


3

Shell globbings are expanded in lexical order by default. If you need a different sort order, you'll need a shell that supports specifying the order like zsh which is probably a good thing since you're already using zsh syntax there (by not quoting $f). for f in ./jobqueue/*(.NOm); do chmod +x $f $f done The (.NOm) part is zsh's globbing qualifiers. ...


3

Here is a quick one-liner that you can type in a terminal: find . -name "*.wav" -print0 | while read -d $'\0' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done You can also use ffmpeg, as @slm suggests, find . -name "*.wav" -print0 | while read -d $'\0' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; ...


3

Not all versions of time support the -o and --output arguments. You will want to run the command like this: (time script.sh) 1> /dev/null 2> /tmp/logFile This will put the output of script.sh into /dev/null and the results to /tmp/logFile. If you want both STDERR and STDOUT to go to the log file you can run it like this: (time script.sh) ...


3

I don't know that there's really a good way to recover this information, if the fields in the middle are blank and you allow the delimiter to go on an unspecified amount of characters, how could you ever tell that the field you end up seeing is Colour and not PlayerName ? At some point the data needs to be formatted in a way that can be parsed ...


3

awk -v field="Game" -v FIELDWIDTHS="10 12 10 13 25" ' NR == 1 {cmpstr="^" field " *$"; for (i=0;i<6;i++) if ($i ~ cmpstr) { fieldindex=i; next;}; exit 1}; {gsub(" ","",$fieldindex); if ($fieldindex != "") print $fieldindex;}' inputfile Edit 1: Exit with error code if not matching column is found. Edit 2: Don't output empty lines.


3

You could use FIELDWIDTHS, though that is a gawk extension and not as portable. You could also name fields as in e.g.: awk ' BEGIN { FIELDWIDTHS = "10 9 13 11 32" team=1; colour=2; game=3; rainfall=4; name=5; } NR == 1 { next } /./ { print $3, $name } ' fixwdata Widths in FIELDWIDTHS is composed as follows: Team Colour Game ...


3

The slashes in the regex are messing up with sed's delimiters. But you can use different delimiters than the slash. For example: sed 's#@base_url = "http://dmstaffing-stage.herokuapp.com/"##' xx


3

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


3

You can use the shuf command to shuffle lines for you. Just backtick a list command where you have *.mp3 and pipe it to shuf, such as: #!/bin/bash SAVEIFS=$IFS IFS=$(echo -en "\n") for i in `find . -maxdepth 1 -type f | grep -Pi "\.mp3$" | shuf` do echo "$i" done IFS=$SAVEIFS Also, if you want to handle spaces, you need to use the "internal field ...


2

You are correct that the pattern is expanded before cp is run, so is unknown to that command. You may be able to accomplish what you want by using the --parents option to cp rather than -R. That will only copy the files which match your pattern, but will use the full path name as supplied rather than only the trailing file name. But, this option isn't ...



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