Tag Info

New answers tagged

0

To get the greater value of $a and $b use this: [ "$a" -gt "$b" ] && $a || $b But you need something around that, you probably don't mean to execute the number, so to display the greater value of the two use "echo" [ "$a" -gt "$b" ] && echo $a || echo $b The above fits nicely into a shell function, eg max() { [ "$1" -gt "$2" ] ...


2

you almost make it awk '(NR>1) && ($8 > 2 ) ' foo > bar where NR is number of record (that is number of line) $8 is eight field && is logical and foo is the original file, unchanged bar resulting file implicit default action is to print the current input line note that header is striped from foo to bar, to keep it awk ...


0

You're almost there! Just tell date to use a format on which computation is easy. lastUpdate=$(date -r myLogFile.log +%s) now=$(date +%s) file_age=$((now - lastUpdate))


0

A basic approach with read and sed (and no error checking): #!/usr/bin/env bash read -p "Enter Client ID: " client read -p "Enter field to change: " field read -p "Enter new data: " data case "$field" in *name) field=2 ;; address) field=3 ;; town) field=4 ;; esac sed -i "/^$client/ {s/[^,]*/$data/$field}" datafile


2

lastUpdate="$(stat -c %Y myLogFile.log)" now="$(date +%s)" let diff="${now}-${lastUpdate}"


1

I would suggest considering a different tool. The 'find' command is very powerful and once you get past some of the syntax rules, easy to use. Example: find /directory -name pattern -perm g=w -exec /bin/rm {} \; This will search for all files and sub folders under /directory that have the group permission of 'write' (logic match to 0020 octal chmod ...


0

compare the two outputs to get the number of seconds between now and the modified date stat -c %Y file vs date +%s


2

With zsh: setopt extendedglob # best in ~/.zshrc extract_numbers() REPLY=${(SM)REPLY##<->-<->} for file (*<->-<->*.dat(no+extract_numbers)) { do-what-you-will-with $file } We define a sorting function (extract_numbers) that returns the Substring of the file name that Matches <->-<-> (<-> matching any positive ...


0

This command will give the filename of only one file sorted by the numeric fields, assuming the pattern is Sample_nnnnnnnnnn-ppp_xyz.dat: ls Sample_$(ls -l *.dat | awk -F ' |_' {'print $10'} |sort -n| head -1)*.dat


1

You can just do a simple sort. Assuming your file names contain no whitespace or other strange characters, this command will always give you the oldest file: find . -name '*dat' | sort -r | tail -n1 If you need to deal with strange characters, use find . -name '*dat' -print0 | sort -zr | tr '\0' '\n' | tail -n1 So, you could do something along the ...


1

assuming all files do not begin with Sample numeric field are sperated by _ you can't relay on file time I would use sort -t_ -k2n which yield for the four files given in sample Sample_0000137294-003_xyz.dat Sample_0000237826-001_xyz.dat Sample_0000237826-002_xyz.dat Sample_0000437564-001_xyz.dat


1

#!/bin/bash ls /tmp/*dat > filelist while read fn do #do something with /tmp/$fn done < filelist


3

look for "history" related commands in the man page for your shell. most shells can write this to a file or set up a repeating prompt command to do it.


0

The "does not save space" message would probably be shown for cases where the program looks at the blocksize of the filesystem on which you are compressing, and realizes that the number of blocks in the resulting file is the same. You can see similar behavior with the zip program. By refusing to compress the file, the developer assumed they were improving ...


1

This will run the awk command on the *.csv files in each subdirectory, leaving behind a {dirname}_appended.dat file in that directory containing the output: for f in */ do awk 'FNR > 1' "$f"/*.csv | sort -sk 1,2 | sort -sk 3,3 >"${f}${f%/}_appended.dat" done Discussion Consider: for f in */ ; do awk 'FNR > 1' *.csv | sort -sk 1,2 | sort -sk ...


1

Shell variable $3 is undefined. You seem to be assuming it is the awk variable $3. And you use wrong syntax (quoting!) in the shell test operation. Do everything in shell, or do everything in awk. In awk... echo "Memory Space Details" free -t -m | awk ' /Total/ { print "Total Memory space : "$2 " MB" print "Used Memory Space : "$3" MB" ...


0

You may use the expect program to supply a response when the password is asked. Note this also has the security problem of hard-coding passwords and is usually better to set a sudo rule for the passwordless execution of the command.


1

You should to remove Win (CRLF) in first line; If you open file in mcedit you will see: !/usr/bin/env php^M change it to !/usr/bin/env php


0

It seems that you need to open a pty. You can try socat: echo pass | socat - exec:su.sh,pty,stderr,su=s3,ctty This way the password is not in the command line arguments, which would be a security issue. The better option would be to modify su.sh in the way that it does not need a password anymore.


0

If you can afford to install external tools, than I would recommend Augeas - this is the only tool for working with config files you will ever need. It represents configs as a tree. Read more here.


4

When you run > /tmp/foo.txt, you are overwriting the contents of /tmp/foo.txt with the output of sed 's/old text/new text/' file1.txt. Since /tmp/foo.txt doesn't exist when you run this command, bash will create that file for you and then write it. Then, when you use the -p flag to cp, you are copying the permissions and attributes of /tmp/foo.txt to ...


2

cropped_2-a.png was renamed to cropped_2.png. This replaced the original cropped_2.png. Then 2 lines later this file was renamed to cropped_4.png. The best way to avoid this problem is to move the files into a different, initially empty, directory when you're renumbering them, so you don't have to worry about any of the new names conflicting with old names. ...


1

With gnu tar you could use: --transform=EXPRESSION, --xform=EXPRESSION Use sed replace EXPRESSION to transform file names. which means --xform='s|path/to/||' would remove path/to/ from the path; and --exclude=PATTERN Exclude files matching PATTERN, a glob(3)-style wildcard pattern. so you could run: tar -zcvf /path/to/compressed/"$(date ...


0

Here's what I ended up using : file1=1stfile file2=2ndfile temp="$(mktemp -dp /mnt/sdcard)" mv "$file1" $temp mv "$file2" "$file1" mv $temp/"$file1" "$file2"


1

Just cd to the folder from where you want the tarball tress structure to start, and use relative paths! So for instance: # Note, one folder above cd /path/to/compress/.. # Tell tar to compress the relative path tar -zcvf /path/to/compressed/file.tar.gz compress When you uncompress it, it will create the compress folder in the current working ...


2

There's no low-level way to swap files, so you need to use an intermediate temporary name. For robustness, make sure that the temporary name won't be used by any other program (so use mktemp) and that it's on the same filesystem as one of the files (otherwise the files would be needlessly copied instead of being just renamed). swap_files () { ...


5

I guess that, in bash anyway, you can use declare and the -global switch to force global scope. Like: total=5 fn(){ local -i total=0 declare -g total=10 echo "$total" };fn echo "$total" ...which prints... 0 10


0

If you have GNU Parallel you can do this: parallel --colsep ' ' ./avg_hrly_all_final.sh {1} {2} :::: ./dates_all.csv If the first line of the csv file is the header you can do something like: parallel --header : --colsep ' ' ./avg_hrly_all_final.sh {Year} {Month} :::: ./dates_all.csv GNU Parallel is a general parallelizer and makes is easy to run jobs ...


3

This is a likely job for xargs: printf %s\\n '#!/bin/sh' 'printf "<%s>\n" "$$" "$@"' >avg_hourly.sh chmod +x ./avg_hourly.sh xargs -n2 ./avg_hourly.sh <<\IN 2005 01 2005 02 2005 03 IN xargs will split on the spaces by default and invoke the specified command once per -n2 occurring arguments. I just wrote a little dummy avg_hourly.sh script ...


1

The thing about the shell's read is - whether you limit its total byte count per read or not - it's still not going to get you a keypress per read. It's only going to get some fixed number of characters per read. In order to get a keypress per read you need to block out your input - and the best way to do that is probably dd. This is a shell function I wrote ...


2

With bash, you can use the -n parameter to the built-in read function to limit the number of characters read without requiring a newline: #!/bin/bash echo "Ready? [Y/n]: " read -n 1 y_or_n echo case "$y_or_n" in [Yy]|"") echo "you said yes" ;; *) echo "you said no" ;; esac This works whether bash is invoked as sh ...


1

Since the awk body is in single quotes, awk does not see the shell variable. awk thinks you mean an awk variable i. That variable is undefined, so in a numeric context it has the value zero. Thus $i is interpreted by awk as $0, or the whole line. You need to pass the shell variable into awk. for ((i=1; i<=$count; i++)) do abc=$(awk -F "," -v col=$i ...


1

You are using abc=$(awk -F "," '(NR==1){print $($i)}' $file). Here you use single quotes around your awk skript. Therefore variables like $i are not replaced by their value. If i=1, awk will therefore literally see $($i) instead of $1 as given in the second example. You can give variables to awk using the -v option. Maybe awk is not the perfect tool for ...


4

Your code can be a lot more concise: #!/bin/bash read -p "Enter file name: " filePath if ! [[ -r $filePath ]]; then echo "cannot read $filePath" exit 1 fi PS3="Where you want to copy? " select host in host1 host2 host3; do if [[ -n $host ]]; then expect <<END spawn scp "$filePath" uname@$host:/usr/tmp ...


7

Your script is attempting to combine two interpreters. You have both #!/bin/bash and #!/usr/bin/expect. That won't work. You can only use one of the two. Since bash was first, your script is being run as a bash script. However, within your script, you have expect commands such as spawn and send. Since the script is being read by bash and not by expect, ...


1

spawn is an expect command. It will not work if your interpreter is /bin/bash.


1

You can do it with xargs + sh -c: <file1.txt xargs -d'\n' -L1 sh -c 'mkdir -p -- "$0" printf %s\\n "function $0() { return stuff; }" >"$0"/function.js' not using the -I {} construct to avoid expansion if your text file contains funky stuff (e.g. lines like - $'\n' \ $PATH).


2

Just loop over all lines in the file: while read line do echo "function $line() { return stuff; }" > "$line/function.js" done < foo.txt Of course this assumes you have already directories named as lines in the foo.txt. If this is not the case then first create them with mkdir "$line". Another approach, with awk instead of loop would be: awk ...


3

As one who has worked in a multitude of ?nix environments, I have had to write in a wide variety of shells. Believe it or not, across platforms, the shells are not the same. So if you maintain your personal library in multiple shells (when necessary) it is very helpful to use extensions to ID the shells. That way when you move to another platform and the ...


0

Try changing this: while getopts :a:b FLAG; do To This: while getopts :a:b: FLAG; do


0

Try the following command line: $ cat file.txt | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b" You may define it as alias and add it to your shell rc files: $ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"' Then every time when you need it, simply go with: $ echo "http%3A%2F%2Fwww" | urldecode http://www When scripting, you ...


0

A dirty solution would look like: boolRememberNext=0 rememberString="" for arg in $*; do if [ ${boolRememberNext} -eq 1 ]; then rememberString="${rememberString} ${arg}" fi if [ "${arg}" = "-name" ]; then boolRememberNext=1 else boolRememberNext=0 fi done echo ${rememberString} | while read filemask; do ...


2

It's because all of your logic depends on one of $OPT_[AB] being null. But even if you don't pass a -[ab] $OPTARG parameter, you're still setting them at the top of the script with OPT_[AB]=[AB]. So your logic chains never get past the root... if [[ -z $OPT_A ]]; then... ...statement. Well... not all of your logic depends on that. You're also doing: ...


0

You don't have a shebang line at the top, so the shell you are using (sh, dash) is likely not to support [[. You should start the script with: #!/bin/bash or any other location bash is in, in the unlikely case that is not the path to bash on your system (type bash).


3

It appears you're trying to use ttyS0 as a means to connect two processes. This won't work reliably since ttyS0 is the interface to a serial line (COM1: in Windows-speak). On the other hand, it might be that information is missing from your question. If you really do have a device on your serial port, please make that clear. What I believe you're looking ...


0

This is script i am running : for d in $(find /backup/ASHISH -maxdepth 1 -type d) do ls -l |awk '{ print $9 }' |grep CC*_date +"%m%d20%Y"|xargs echo echo $d done >test.out This script is giving me output as /backup/ASHISH/D /backup/ASHISH/E /backup/ASHISH/R /backup/ASHISH/CL /backup/ASHISH/E /backup/ASHISH/C I expect shell script to return all the ...


1

Use a for loop: for d in $(find /path/to/dir -maxdepth 1 -type d) do #Do something, the directory is accessible with $d: echo $d done >output_file It searches only the subdirectories of the directory /path/to/dir. Note that the simple example above will fail if the directory names contain whitespace or special characters. A safer approach is: find ...


1

I am a complete bash newbie, but a UN*X veteran. Although doubtless this can be done in Bash shell scripting, in the old days we used find [-maxdepth <levels>] <start-dir> -exec <command> ; to achieve this. You could do a man find and play around, perhaps until someone tells you how to do it in bash!


1

Bash makes it relatively easy to apply a transformation like stripping prefixes and suffixes to elements of an array. shopt -s nullglob # if there are no matches, produce an empty list versions=(hsli*.h5) # list matches versions=("${versions[@]#hsli}") # strip prefix versions=("${versions[@]%.h5}") # strip suffix printf ...


2

Without ls, since you're just populating its list with shell globs anyway, you can cut out the middle-man like: glob_hsli()(IFS=.;set +f set -f -- '' hsli*.*.h5 for h5 do case ${h5#*.} in (*[!0-9]*.*|.*|'') : ;; (*) set $h5 "${1:-0}"; shift $((3>>($2>$4)));; esac;done printf "0.%d\n" "${1:?No Match Found!}" ...



Top 50 recent answers are included