Tag Info

New answers tagged

1

Substitution is almost synonymous with expansion in this context because their meanings overlap. Neither is quite a complete sub category of the other, although in the GNU Manual section you reference there are substitutions that are considered as part of an overall expansion. An expansion is taking the value of an identifier. E.g., if this=that, when we ...


1

set -- arg arg2 echo ${2+"$1"} #OUTPUT arg shift echo ${2+"$1"} #OUTPUT #there doesn't seem to be anything here I think the difference is generally too minimal to be worthy of notice - and the terms are often used interchangeably. Though, if you look at the above two cases, you can see that in the first example we substitute $1 for $2 as a result of ...


3

With this approach (function running in a subshell) you aren't going to be able to update the master shell process's state without going through contortions. Instead, arrange for the function to run in the master process. The value of the PROMPT_COMMAND variable is interpereted as a command which is executed before printing the PS1 prompt. For PS2, there's ...


0

awk 'c&&!--c;/img class=\"devil_icon/{c=4};/img class=\"devil_icon/' input.txt You're essentially doing a find and replace. You can add just a find into the same command and it'll print both of them :) awk 'c&&!--c;/pattern/{c=4};/pattern/' input.txt


1

You can not use a shell variable this way and you already understand why. A subshell inherits variables exactly the same way a process inherits its environment: any changes made apply only to it and its children and not to any ancestor process. As per other answers the easiest thing to do is stash that data in a file. echo $count > file ...


0

For reference, here’s my solution using temporary files, which are unique per shell process, and deleted as soon as possible (to avoid clutter, as alluded to in the question): # Yes, I actually need this to work across my systems. :-/ _mktemp() { local tmpfile="${TMPDIR-/tmp}/psfile-$$.XXX" local bin="$(command -v mktemp || echo echo)" local ...


2

It's a bit I/O-intensive, but you'll need to use a temporary file to hold the value of the count. ps_count_inc () { read ps_count < ~/.prompt_num echo $((++ps_count)) | tee ~/.prompt_num } ps_count_reset () { echo 0 > ~/.prompt_num } If you are concerned about needing a separate file per shell session (which seems like a minor concern; ...


4

To get the same output you note in your question, all that is needed is this: PS1='${PS2c##*[$((PS2c=0))-9]}- > ' PS2='$((PS2c=PS2c+1)) > ' You need not contort. Those two lines will do it all in any shell that pretends to anything close to POSIX compatibility. - > cat <<HD 1 > line 1 2 > line $((PS2c-1)) 3 > HD line ...


0

Redirect stderr to the file that stdout points to, then redirect stdout. That allows you to capture the error message sftpError=$( sftp $TragetUsr@$TargetserIP <<-FIL 2>&1 >> $LOGPATH/$Logfile cd $FTPDir lcd $FILEPATH put $ZipFilename bye FIL )


0

Well, if you always have the same number of fields per record and you don't have anything between records (assumptions I'm making based on your post which may or may not be correct), you could go the awk route. This will preserve column order and embedded newlines. Assume the following is in parse.awk: BEGIN { RS = "( = |\n\\s+)"; isHeader = ...


2

Obviously, use another symbol instead of %. Use for example -I @. So it will be: ( cd "${SOURCE_DIR}" && find . -type f -name "${FILE_GLOB}" ) | xargs -n 100 | xargs -I @ sh -c '{tar -C "${SOURCE_DIR}" --files-from - @ -cf "${DESTINATION_DIR}/$(date '+%Y%m%d%H%M%S%N')-$(uname -n).tar~"}'


1

The problem is that the shell redirection (<) sends the file over the ssh tunnel. And the Java class is expecting not the file, but a string with the "filename" of a local file that will be read with a FileReader. Instead of passing the filename to the FileReader, read from the standard input. InputStreamReader isReader = new ...


-1

The local file, by definition, is on your local machine. The java program is on a remote machine. The remote machine does not know about your local file, and in any production situation probably does not have permission to read it. I can think of three general approaches to this situation: 1) Change your Java program to read from stdin instead of from a ...


0

This is very simple to do with awk, however the standard approach is to output to a temporary file and then replace the original, using Linux mktemp you can do: tempfile=$(mktemp --tmpdir=.) awk -F= '{ if($1=="report.lookback.days.to.retrieve.data") print $1"="$2+1 else print }' in_file >"$tempfile" mv "$tempfile" in_file Some versions of ...


1

If you just want to edit a file that looks like what you posted, use something like perl -i -pe 's/report.lookback.days.to.retrieve.data=\K\d+/$&+1/e' file Explanation The -i enables in-place editing, so the changes are saved to the original file, -p means "print each line after executing whatever script is givven by -e"/ The s/// is the ...


1

If you just want to edit the file in place each day, which you probably don't want to do, you could do something like this: $ echo 'report.lookback.days.to.retrieve.data=61' \ | awk -F= ' /report.lookback.days.to.retrieve.data/{ printf("%s=%d\n", $1, $2+1) } ' report.lookback.days.to.retrieve.data=62 But that would ...


3

I don't know anything about Java, but I can show you a proof of concept. Say we have localfile.txt: Here is the local file. and on the remote machine, we have remote.sh: #!/bin/bash cat /dev/stdin Note that the script on the remote machine invokes a program which reads from stdin. Then pass the contents of localfile.txt to your ssh command: ...


2

I think I would've done this using find but just to help answer your scripting questions I've modified your example slightly. #!/bin/bash for d in *; do # First level i.e. 2014, 2013 folders. regx='^[0-9]+$' # Regular Expression to check for numerics. echo "dir: $d" if [[ $d =~ $regx ]]; then # Check if folder name is ...


4

You can use bash extended globbing for this: shopt -s extglob DIR_UPLOADS=/home/html/wp-content/uploads/ cd ${DIR_UPLOADS} for dir in $PWD/+([0-9])/+([0-9]); do cd "$dir" && for file in *; do echo 'Compress Image' done done From the man page: +(pattern-list) Matches one or more occurrences of the given patterns So putting a ...


8

The most important difference between bash -c "$1" And eval "$1" Is that the former runs in a subshell and the latter does not. So: set -- 'var=something' bash -c "$1" echo "$var" OUTPUT: #there doesn't seem to be anything here set -- 'var=something' eval "$1" echo "$var" OUTPUT: something I have no idea why anyone would ever use the ...


11

eval "$1" executes the command in the current script. It can set and use shell variables from the current script, set environment variables for the current script, set and use functions from the current script, set the current directory, umask, limits and other attributes for the current script, and so on. bash "$1" executes the command in a completely ...


2

I did a quick test: time bash -c 'for i in {1..10000}; do bash -c "/bin/echo hi"; done' time bash -c 'for i in {1..10000}; eval "/bin/echo hi"; done' (Yes, I know, I used bash -c to execute the loop but that should not make a difference). The results: eval : 1.17s bash -c : 7.15s So eval is faster. From the man page of eval: The eval utility ...


1

Please try reading some documentation before posting here. What you're asking is trivial to find with a 5 minute google search. You might want to read through our Help page on how to ask questions to get a better idea of how this site works. Anyway, you can either pass variables as arguments using the -v option: awk -F'[]]|[[]' -v var1="2014-04-07 23:00" ...


2

What you are looking at here is called programmable completion. On Debian/Ubunutu based systems, packages will often install a file to /usr/share/bash-completion/completions which provides the programmable completion for the command. On other distributions the /etc/bash_completion.d directory may be used (this location is deprecated on Debian/Ubuntu, but ...


8

This facility is being done by what's called Bash Completion. The files that back this are stored under /etc/bash_completion.d with each command having its own file. So in the git case: /etc/bash_completion.d/git If you look at this file you'll notice that it's overloading your environment with extra functions. One in particular is this guy: $ ...


2

Probably you have a very old (1.x) version of fish installed, which predates the else-if construct. What does fish --version output? Ideally you want 2.1.0.


2

_fn() { set -- "$@" $(cat) while ${1+:} false ; do echo "$1" && [ "$1" = "arg2" ] && echo "$1" $YOUR_CHK shift done } echo "arg2" | _fn "arg1" OUTPUT arg1 arg2 arg2 That handles both cmd-line args and stdin. It only runs the while loop to check them while you still have at least one argument saved in ...


3

This is not a problem which should be solved with regex (although technically you could find a way to do it). Since you are going to be using this more than once, you might want to use some real datetime functions rather than just parsing strings. The following Awk script may work for you. # Expects time strings in the form of `[2014-04-25 15:38:23]` with ...


1

Using sed : #!/bin/bash E_BADARGS=23 if [ $# -ne "3" ] then echo "Usage: `basename $0` \"<start_date>\" \"<end_date>\" file" echo "NOTE:Make sure to put dates in between double quotes" exit $E_BADARGS fi isDatePresent(){ #check if given date exists in file. local date=$1 local file=$2 grep -q "$date" ...


1

One alternative to awk or a non-standard tool is to use GNU grep for its contextual greps. GNU's grep will let you specify the number of lines after a positive match to print with -A and the preceding lines to print with -B For example: [davisja5@ehsbbrlp01 ~]$ cat test.txt Ignore this line, please. This one too while you're at it... [2014-04-07 23:59:58] ...


4

Check out dategrep at https://github.com/mdom/dategrep Description: dategrep searches the named input files for lines matching a date range and prints them to stdout. If dategrep works on a seekable file, it can do a binary search to find the first and last line to print pretty efficiently. dategrep can also read from stdin if one the filename ...


8

You can use awk for this: $ awk -F'[]]|[[]' \ '$0 ~ /^\[/ && $2 >= "2014-04-07 23:00" { p=1 } $0 ~ /^\[/ && $2 >= "2014-04-08 02:00" { p=0 } p { print $0 }' log Where: -F specifies the characters [ and ] as field separators using a regular expression $0 references a complete line $2 ...


1

By default, if you use: update-rc.d server defaults then update-rc.d will make links to start your server service in runlevels 2345 and to stop in runlevels 016, all these links have sequence number 20. If server script depends on other services, e.g networking. So when server script start while its depending services haven't started yet, it will fail. ...


1

All you need is printf. It's the print function - that's its job. printf '%s\t%s\n' ${array[@]} You do it like this: ( set -- 12345 56789 98765; for i ; do eval set -- $(printf '"$%s" ' `seq 2 $#` 1) echo "$*" done ) OUTPUT 56789 98765 12345 98765 12345 56789 12345 56789 98765 I didn't need eval - that was dumb. Here's a better one: ( set ...


2

Assuming that each filename you are processing has the same length and that each substring has the same length, you can split based on this. Also, sure where the -1 part on the ID comes from, so I assume you get it from lane_1. for file in *_P1* do id=${file:0:18}-${file:24:1} pu=${file:8:10} lb=${file:0:7} echo "id=$id pu=$pu lb=$lb" done ...


1

I found out the way to print the elements in 2 element sized combinations. The php code is as below. <?php function pc_array_power_set($array) { // initialize by adding the empty set $results = array(array( )); foreach ($array as $element) foreach ($results as $combination) array_push($results, ...


1

You might take a look at rsync, if you're not already familiar with it. This looks like a problem that shouldn't really require a script of its own. Take a look here, or use your Google foo. The rsync option you need is probably --files-from. The rsync incantation will be something like: rsync --files-from filenames.txt /root/Backup/upload ...


3

file=/path/to/filenames.txt fromPath=/root/Backup/upload/ toPath=/root/Desktop/custom/upload/ cd "$fromPath" && xargs mv -t "$toPath" < "$file"


2

An solution using awk: $ awk -F'=' '$1 ~ /^[ \t]*file.input[ \t]*$/{$2="= /new/name"}{print}' config # file.input = /very/old/name # file.input = /old/name file.input = /new/name file.input.default = /default/name other.file.input = /current/other/name # Other comments other.properties = must stay the same Then you can save it to new config file: awk ...


3

Using the -i option of sed (which edits inplace). The caveat is the character used to delimiter the substitution command must not appear in the NEW string. The example uses ':' rather than '/' to delimit (s:old_string:new_string:) NEW=/new/name sed -i 's:^[ \t]*file.input[ \t]*=\([ \t]*.*\)$:file.input = '${NEW}':' f


1

An easy way is to use lockfile coming usually with the procmail package. LOCKFILE="/tmp/mylockfile.lock" # try once to get the lock else exit lockfile -r 0 "$LOCKFILE" || exit 0 # here the actual job rm -f "$LOCKFILE"


2

in this issue i recommend use pssh. Thx pssh you could very easy run command on many remote servers at once. put host into (i.e hosts_file)- each server in 1 line like: host1.tld host2.tld Usage: pssh -h hosts_file "COMMAND" in you example it will be pssh -h hosts_file "ls -l /etc/foobar"


0

for host in host1 host2 host3 ;do ssh $host 'echo -n "[$(hostname -s)]"; /sbin/ifconfig |grep Bcast' ;done [host1] inet addr:xxx.xxx.138.30 Bcast:xxx.xxx.143.255 Mask:255.255.248.0 [host2] inet addr:xxx.xxx.138.14 Bcast:xxx.xxx.143.255 Mask:255.255.248.0 [host3] inet addr:xxx.xxx.82.146 Bcast:xxx.xxx.82.255 ...


-1

You can use ftp commands inside a shellscript in the following way: ftp -dv ${SSHHOST} >$dirFtp/$fichFtpLog <<_FINFTP_ ascii put ${dirwork}/${fichSalida} ${rutaSubida}/${fichero} close quit _FINFTP_ dirwork/fichSalida ... are shellscript vars as example. You have to note that in order to use ftp in this way, you must configure ...


1

You can do this with = operator, like [ $(cat /path_of a file/) = 1 ]. It compares string representations of both arguments so it will work in all cases. Using -eq instead of string comparison may be preferable in some cases ([ 01 -eq 1 ] is true while [ "01" = 1 ] is not) but in most cases it's just more dangerous. If, on the other hand, you really need ...


0

Variable in bash is untyped. If you want the condition to always get evaluated with integers, you can use delcare -i to make variable always an integer. From bash manpage: declare [-aAfFgilrtux] [-p] [name[=value] ...] ..... -i The variable is treated as an integer; arithmetic evaluation (see ARITHMETIC EVALUATION above) is performed when the ...


9

The line assigning mailbody is wrong. You're calling the contents of $body and/or $body1 as a shell command line. Replace mailbody=$([ "$applicationstatus" == 200 ] && $body || $body1) With [ "$applicationstatus" = 200 ] && mailbody="$body" || mailbody="$body1"


2

Just so you know - you're not limited to a single command per |pipe: this happens | then this | { then ; all of ; this too ; } | before this All of those processes are invoked at the same time - but they all wait on the |pipe before them before actually doing anything - so long as they read the |pipe at all, that is. So, if you need to evaluate a variable ...


4

It sounds like you want something like this (although it's not clear what you mean when distinguishing "iterative command" from "recursive command", since rm -rf is both recursive and iterative): find . -type d -name '.[^.]*' -prune -exec echo rm -rf {} + Once you're happy, remove echo from the option arguments to -exec to remove the listed directories.


1

Try this (uses GNU split which is default on most Linux distros): ls | sed "s:^:$(pwd)/:" | split -dl 50 --additional-suffix=.txt - /path/to/dest/File



Top 50 recent answers are included