Tag Info

New answers tagged

2

You cannot pass two arguments with single option using getopts. As an alternative I recommend to put quote around two (multiple) of arguments, so that getopts will treat this as one argument, but you will be able to split it later on. You can even put all arguments in the array at once: #!/bin/bash while getopts ":hr::l:" opt; do case $opt in ...


0

You can use the construction : <<"SOMEWORD" ... SOMEWORD which substitute the commenting by # ##### The following "code block" is effectively ignored : <<"SOMEWORD" /etc/init.d/mydatabase clean_stop mydatabase_dump /var/db/db1 /mnt/fsrv0/backups/db1 logger -t SYSHALT "System halt: pre-shutdown actions done, now shutting down the system" shutdown ...


0

POSIX defines the -p option to the command builtin so... -p Perform the command search using a default value for PATH that is guaranteed to find all of the standard utilities. Taken with the -v and -V options for either parsable or human-friendly (respectively) output regarding a command's location, and you can pretty well rely on it to get you the ...


2

I don't think this is possible in dash. As far as I can tell from its man page, it has no support for process substitution. As a workaround, you could try what mikserv suggested, or you can redirect everything to a file, and then after your script is finished (presumably this is in a script), add that file's contents to logger: $ exec > ~/foo/foo.txt $ ...


3

You can just do: { commands .... } | logger -t my_awesome_script You can do that with any shell. If you don't like the way it looks, maybe make the script wrap itself in a function. #!/bin/sh run() if [ "$run" != "$$" ] then run=$$ exec "$0" "$@" | logger -t my-awesome-script fi #script-body run || do stuff


2

To make "playing" with variables a little shorter c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3 for var in file album band do eval "$var=\${c##*/}" c=${c%\/${!var}} done echo $file $album $band music-file.mp3 album-name band-folder Other way is to use read command IFS=/ read -r band album file <<< ...


1

The previous solutions seem overly complicated to me. The following seems to me to be the simpliest solution. To get the directory name of a filename strings in bash dirname "$varcontainingfilename" To get the ONLY the filename from a filename string in bash use basename "$varcontainingfilename" From this base you should be able to easily do what ...


2

When referring to $c if by filename you mean full-path to file then this job is really very easy. There are a few ways to do it. Using just POSIX shell globs and parameter expansion you can do: c='/home/user/working-root-directory/band-folder/album-name/music-file.mp3' file=${c##*/} album=${c#*"${c%/*/"$file"}"/} band=${c#*"${c%/*/"$album"}"/} ...


1

Zsh is a much more elegant solution, but if it is not your shell, you can useawk: printf "%s\n" "$path" /home/user/working-root-directory/band-folder/album-name/music-file.mp3 band=$(awk -F/ '{print $(NF-2)}' <(printf "%s" "$path")) printf "%s\n" "$band" band-folder album=$(awk -F/ '{print $(NF-1)}' <(printf "%s" "$path")) printf "%s\n" "$album" ...


1

I would hire zsh for this job: $ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3' $ echo $c:h /home/user/working-root-directory/band-folder/album-name $ echo $c:h:h /home/user/working-root-directory/band-folder $ echo $c:h:h:h /home/user/working-root-directory (...) $ echo $c:t filename.mp3 $ echo $c:h:t album-name $ echo ...


1

I've stepped into this problem myself and decided to do some tests. I fully agree with the answer that one should package for each distro separately, but sometimes there are practical issues that prevent that (not least manpower). So for those that want to "auto-detect" here's what I've found out on a limited set of distros (more below): You can tell ...


0

If you only want to backup the directory you specify this should work: Place this script in the directory you want to backup: #!/bin/bash #Check if "backups" exists / if not create folder if [ ! -d "backups" ] then mkdir backups fi #Begin Backup #Choose if you want to use gzip or just tar #TAR with gzip #tar -cvfz --exclude=backups ...


1

A simple 1 liner solution: find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \; http://lewisdiamond.blogspot.ca/2012/01/converting-flac-to-mp3.html Note that this will be applied recursively in the given directory. I.e. if you run this from your Music folder, it will convert all flacs from subfolders and produce a .mp3 next to it. ...


0

I'm not entirely sure I understand what you're after either but type and which should help. For example: $ type -a sudo sudo is aliased to `/usr/bin/sudo' sudo is /home/terdon/scripts/sudo sudo is /usr/bin/sudo In the example above, there are 3 possible sudos, one is an alias and two are in my $PATH. You can just parse that to do what you want. If you are ...


0

Maybe you're using zsh. Try adding as the first line of the file, #!/usr/bin/zsh.


2

You can install ImageMagick and use the identify tool with -verbose, for example: for f in *.jpg *.jpeg *.JPG *.JPEG *.mp4 *.MP4; do echo $f identify -verbose "$f"|grep exif:DateTime echo done Kepler22b-artwork.jpg Kepler-62f_with_62e_as_Morning_Star.jpg exif:DateTime: 2013:04:08 10:45:44 logo.jpg P1050030.JPG exif:DateTime: 2013:11:01 ...


0

If your $HOME/bin path are not in $PATH you could test it with if [ ! -a $(command -v $(basename $0)) ]; then YOUR SCRIPT else echo "$(basename $0 already exists in $PATH" fi


4

Could use awk for the whole thing. Awk is also far quicker than while read loops. awk -vM="$Message" '$1==M{print "Translated:",$2"-"$3}' CODE-LIST.txt Explanation -vM="$Message" - Create a variable named M with the value from $Message $1==M - If the first field is equal to variable M($Message) {print "Translated:",$2"-"$3} - ...


2

Out of curiousity whether a multi-threaded Python script would reduce the running time, I created this digest.py script which uses threading.Thread, threading.Queue and hashlib to calculate the hashes for multiple files. The multi-threaded Python implementation is indeed slightly faster than using pee with coreutils. Java on the other hand is... meh. The ...


5

There is no need for scripting or functions. If you simply put $HOME/bin last in your path, it will only be used if there is no matching command name in any of the previous directories in the $PATH. Example: [jenny@sameen ~]$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin [jenny@sameen ~]$ which foo /usr/bin/which: no foo in ...


1

Search for the command with a modified PATH: PATH=$(awk -F: 'sub(FS "'$HOME/bin'","")' <<<"$PATH") which sudo For example: $ which sudo /usr/local/bin/sudo $ PATH=$(awk -F: 'sub(FS "/usr/local/bin","")' <<<"$PATH") which sudo /usr/bin/sudo


6

How about: while read code device state junk; do if [[ $code == $message ]]; then echo "Translated: $device-$state" fi done <CODE-LIST.txt Using extra processes (i.e. forking awk everytime) will slow it a lot. read will read multiple fields, separated by $IFS (default value is all white space). The last variable listed will receive the ...


1

Jacksum is a free and platform independent utility for computing and verifying checksums, CRCs and hashes (message digests) as well as timestamps of files. (excerpted from jacksum man page) It is large file aware, it can process filesizes up to 8 Exabytes (= 8,000,000,000 Gigabytes), presupposed your operating system respectively your file system is large ...


0

You could do something like this: awk -F: '{ print $1" "$5 }' /etc/passwd | sort -k2 This will parse the username and comment fields from /etc/passwd and sort on the second field which will be the first name of the user, provided they are listed in first name and last name order. Here is an example of incorporating grep: grep "500\|501\|502" ...


0

You have to do it: grep mohsen /etc/passwd | awk -F':' {'split($5,a,",");printf "username is :%s ,uid is: %s , name is %s \n",$1,$3,a[1] '} Output is: username is :mohsen ,uid is: 1000 , name is Mohsen Pahlevanzadeh


1

My script works, if both your values separated by the delimiter have the same amount of characters. I hope it'll help a little. EDIT: I've rewritten the code, so it takes an arbitrary number of lines. But now I see, you've added information, that more than one delimiter is possible :-) I'll look at it later. If you wanted arbitrary number of spaces, it ...


2

I think your approach is correct, and tracking the cookie is a robust way of doing this. However, the only place in the source of inotify-tools (3.14) that cookie is referenced is in the header defining the struct to match the kernel API. If you like living on the edge, this patch applies cleanly to 3.14 and adds a %c format specifier for the event cookie ...


2

Hitting Enter the script ends the process remains in the background. Almost! Actually, the script has already exited by the time you press Enter. However, that's how you can get your prompt back (because your shell prints its $PS1 all over again). The reason why hitting Ctrl + C terminates both of them is because the two of them are linked. When you ...


1

There's a missing quote... You should really check your code, at least with a syntax highlighter. This line... if [ "$LOGNAME != "root" -o $groufind != "system" ]; Should be: if [ "$LOGNAME" != "root" -o $groufind != "system" ]; Now for the rest, I'm gonna have to guess because your code sample is nothing close to helpful: This weird scope at the ...


17

Check out pee ("tee standard input to pipes") from moreutils. This is basically equivalent to Marco's tee command, but a little simpler to type. $ echo foo | pee md5sum sha256sum d3b07384d113edec49eaa6238ad5ff00 - b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c - $ pee md5sum sha256sum <foo.iso f109ffd6612e36e0fc1597eda65e9cf0 - ...


6

You can use a for loop to loop over the individual files and then use tee combined with process substitution (works in Bash and Zsh among others) to pipe to different checksummers. Example: for file in *.mkv; do tee < "$file" >(sha256sum) | md5sum done You can also use more than two checksummers: for file in *.mkv; do tee < "$file" ...


4

You could always use something like GNU parallel: echo "/path/to/file" | parallel 'md5sum {} & sha256sum {}' Alternatively, just run one of the two in the background: md5sum /path/to/file & sha256sum /path/to/file Or, save the output to different files and run multiple jobs in the background: for file in *; do md5sum "$file" > ...


4

It's a pity that the openssl utility doesn't accept multiple digest commands; I guess performing the same command on multiple files is a more common use pattern. FWIW, the version of the openssl utility on my system (Mepis 11) only has commands for sha and sha1, not any of the other sha variants. But I do have a program called sha256sum, as well as md5sum. ...


5

You don't really need both grep lines, instead you might as well put: if grep -q "$input_string" "$input_string1" ; then echo "Your string has been found" else echo "Your string has not been found" fi


2

Another (a little bit more compacted) version with sprintf: awk 'BEGIN{FS=OFS=","} $4 ~ /"RENT OUT"/ {$12=sprintf("\"REP%04i\"",++i);i=i%100}1'


3

I believe that this does what you want: $ awk 'BEGIN{FS=",";OFS=","} $4 ~ /"RENT OUT"/ {NF--;printf $0; x=x%100;x++; printf ",\"REP%04i\"\n",x;next} 1' rentals.csv "00:30:00","01:00:00","10/14/2014","RETURN","PASADENA","TX","12:30:00","sedan","","","corporate","CO01353" "01:00:00","01:30:00","10/14/2014","RENT ...


2

Similar to @lgeorget's answer, this adds a newline before any ":61:" that is not at the beginning of the line: perl -pe 's/(?<!^)(?=:61:)/\n/g' file


2

To append $ID (with space) at the beginning of each line something like sed "s/^/$ID /" should work (notice double, not single quotes). If you want to do this within the given loop and redirect output to report.txt try for ID in {92..128}; do sed "s/^/$ID /;3q;d" directory_$ID/stats done > report.txt


0

Are you using symlinks ? To write reliable scripts, you should not be using "dirname $0". It relates to the $0 command, which is related to the calling command. If you are navigating across directories, use instead "readlink -f $0". basedir="$(dirname $(readlink -f $0))" $basedir/../filename {options} {parameters} & readlink -f will give you the ...


3

Here is a very simple solution which works perfectly on your example: sed 's/ :61:/\n:61:/g' < input_file You may have to adapt it a little, especially if you don't always have a space before :61: in your input files.


0

You could do it all in awk i think awk ' function readfile(i){ file="RD00"i"/MergerHalos.out" while ( (getline < file) > 0) { if(NR < 15 && $8 >0.48 && $8 <0.52 && $9 >0.48 && $9 <0.52 && $10 >0.48 && $10 <0.52) print i":"$1,$8,$9,$10 > center_raw.dat ...


1

A quick rewrite stylistically (more DRY) for (( c=sta; c<=end; c++ )); do awk -v c=$c ' NR == 15 {exit} function ok(val) {return (0.48 < val && val < 0.52)} ok($8) && ok($9) && ok($10) {print c, $1, $8, $9, $10} ' RD00$c/MergerHalos.out done >> center_raw.dat


3

I am not sure what your requirement is but from what i infer below seems to be what you require: awk -v var="$c" '{if (NR < 15 && $8 >0.48 && $8 <0.52 && $9 >0.48 && $9 <0.52 && $10 >0.48 && $10 <0.52) {print var ":" $1 " " $8 " " $9 " " $10}}' RD00$c/MergerHalos.out >> ...


5

Get rid of the commas in the userid list. The way to pass a list to a for loop is to give it space separated values, not comma separated: for userid in 234, 283, 893, 982, 323; do echo "$userid";done prints 234, 283, 893, 982, 323 But for userid in 234 283 893 982 323; do echo "$userid";done prints 234 283 893 982 323 So, you should do for ...


0

Neither of the first two conditions are met, so the else block is executed which consists of: [[ "$battery_level" -le "5" ]] # evaluates this, which does nothing notify-send ... # shows the message you are seeing Here's what you want: #!/bin/bash # Battery level warning ...


0

So after setting up SSH keys and NOPASSWD entry in teh sudoers file, you could do something like #!/bin/bash if [[ ${UID} -ne 0 ]] ; then echo "Must run script as root" >&2 exit 1 fi launchctl unload /Library/LaunchDaemons/com.plex.plexconnect.bash.plist #check what is running on port 80 and if the output matches 'python' then print the ...


0

Found solution: clean and easy for i in ${array1[@]};do echo -e "PACKAGE NAME:$i " >> MANIFEST2 && echo -e "PACKAGE SIZE: `xz -l $i |tail -n 1|cut -d . -f 1|awk '{print $3, "K"}'`" >> PACKAGES.TXT PACKAGE NAME:a/pam-1.1.8-x86_64-2mg.txz PACKAGE SIZE: 453 K PACKAGE NAME:x/tvtime-1.0.2-x86_64-3_SBo.txz PACKAGE SIZE: 606 K


0

This works on your example input line: sed 's/.* \([0-9].*)\) .*>/(\1: RAW DATA OUT:/ ' <<\DATA 1: (10/17 12:49:31.175) - CONSTANT ID1 - CONSTANT ID2: RAW DATA OUT > [0x00,0xa2,…,0x00] DATA It prints: (12:49:31.175): RAW DATA OUT : [0x00,0xa2,…,0x00]


1

(Your loop has uneeded `` causing the problem via command substitution, as noted by val0x00ff and Patrick. This is for the second part about finding another way to solve the problem.) You can show the number of file-descriptors per process using lsof directly: lsof -Fpcn | nawk ' /^p/ { pid=substr($0,2) } /^c/ { cmd=substr($0,2) } /^n/ { ...


1

You can also call perl from bash. The -n arg makes it loop for each line. -e means the script is one line. cat in.txt | perl -ne 's{.*(.*\().*? (.*) -.*(:.*?)\s\s+.*(\[.*)}{$1$2$3 : $4};'



Top 50 recent answers are included