Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
12

With read, -d is used to terminate the input lines (i.e. not to separate input lines). Your last "line" contains no terminator, so read returns false on EOF and the loop exits (even though the final value was read). echo '0,1,2,3,4,5' | { while read -d, i; do echo "$i"; done; echo "last value=$i"; } (Even with -d, read also uses $IFS, absorbing whitespace ...


10

This renames all .mp4 files, without parsing ls: i=1; for file in *.mp4; do mv "$file" $(printf "video_%03d.mp4" "$i"); i=$((i + 1)); done Any glob can be used in the for file in ... statement. You could apply other criteria by using find instead.


8

As other answers state, -d is an end-of-line character, not a field separator. You can do IFS=, read -a fields <<< "1,2,3,4,5" for i in "${fields[@]}"; do echo "$i"; done


8

aws efs describe-mount-targets --file-system-id ${SharedFileSystem} \ | jq --arg mntsrc "$MOUNT_SOURCE" '.MountTargets[].IpAddress | . + $mntsrc' -r >> /etc/hosts or, if you prefer, aws efs describe-mount-targets --file-system-id ${SharedFileSystem} \ | jq '.MountTargets[].IpAddress' -r | sed -e "s~\$~$MOUNT_SOURCE~" >> /etc/hosts All ...


8

Using pgrep: grep -Po '(^|[ ,])KEY1:\K[^,]*' or egrep and cut: grep -Eo '(^|[ ,])KEY2:[^,]*' | cut -d: -f2- For both methods, the Value is not allowed to contain comma. If you had proper json, e.g. { "KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3" } you could use jq: jq ".KEY2"


7

I would use the standard UNIX editor (of course!): for f in ENSG* do printf '1i\n\t%s\n.\nw\nq\n' "$f" | ed -s "$f" done This sends a small script of commands to ed, namely: at line 1, insert (i) some text; the text is passed through printf as the filename, preceded by a tab (\t) after inserting that text (.), save the file to disk (w) and quit (q) If, ...


6

In a loop: shopt -s nullglob files=() for number in "${clipnumbers[@]}"; do printf -v pattern 'clip%s-*.png' "$number" files+=( $pattern ) done This loops over the numbers and creates a filename globbing pattern for each. The pattern is expanded to add the filenames matching it to the array files. The nullglob shell option makes non-matching ...


5

From man: -d delim The first character of delim is used to terminate the input line, rather than newline. Your element 5 doesn't have a delimiter (comma), so it won't be read.


5

Don't parse the output of ls. Instead, use find(1): find . -type d


4

Unix V7 was released in the late 70s. That's the version that introduced the Bourne shell. However, at that time, function support hadn't been added yet, read didn't have -r, there was no printf command. Case insensitive grep was with grep -y. And of course $(...) is not Bourne. Unix-like systems have evolved quite a bit since then and diverged. In the ...


3

Option #1 Similar to Kusalananda's answer but with array expansion instead of a loop: setup $ touch clip12710-x.png clip30443-x.png clip57592-x.png clip76672-x.png clip93493-x.png $ declare -a array=([0]="30443" [1]="76672" [2]="42424") Note that the array contains only two items that are expected to match; there are filenames with clips that are not ...


3

What you're seeing is the same behavior (and for the same reason) as Why does this 'while' loop not recognize the last line? As in that case, you can modify the behavior by adding an extra test to the loop termination condition, as follows while read -d, i || [[ -n $i ]]; do ... Ex. $ echo '0,1,2,3,4,5' | while read -d, i || [[ -n $i ]]; do echo $i; done ...


3

Alternatively, still using ed, with zsh, a single invocation and no command-line limit (length or number of arguments): printf 'e %s\n1i\n\t%1$s\n.\nw\nq\n' * | ed (zsh’s printf supports %m$ specifiers to re-use arguments.)


2

With zsh: clipnumbers=(01234 33333) files=(clip$^clipnumbers-*.png(N.)) That expands one glob per clip number. Alternatively, you could turn the array into a glob alternation operator: files=(clip(${(j:|:)~clipnumbers})-*.png(N.))


2

Your question does not provide a lot of context to determine what it is you actually want to accomplish, but man bash is clear that with set -e your script will exit immediately when a non-zero exit status is received, Except if the failing command is part of: the command list immediately following a while or until keyword; the test following the if or elif ...


2

Solution: awk '/^Page [0-9]+$/ {N = $2} {print > "page"N}' pages Test run: ==> page1 <== line 1 line 2 line 3 line 4 line 5 ==> page2 <== line 1 line 2 line 3 line 4 line 5 ==> page3 <== line 1 line 2 line 3 line 4 line 5


2

Use separate move commands: ex -sc 'g?_005?m0' -c 'g?_004?m0' -c 'g?_003?m0' -c 'g?_002?m0' -c 'g?_001?m0' -c wq target_file Note that: I'm using ex (actually, Vim) here, not ed. You can specify the ex-commands in the command line using the -c option, so printf isn't needed. The patterns must be in reverse order (005 gets moved to the top first, then 004, ...


2

Use awk: awk -F'[0-9]' ' BEGIN{ x["H"]=1; x["O"]=8; x["C"]=6; x["Br"]=35; } { print $0" = "x[$1]; } ' input_file > output_file Output: H1 = 1 O1 = 8 C1 = 6 H2 = 1 H3 = 1 O2 = 8 C2 = 6 Br1 = 35


2

Your script doesn't work the way you expect it because of the order of expansion. From the bash manual: The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion. As you see, brace expansion is ...


2

awk '!seen[$2]++' file This will print only lines which are unique in the second column. Output: WP_021815421.1 OG5_132922 deth|YP_182312 3 -07 42.35 81.7 WP_021815427.1 OG5_128110 ...


2

tail -f is meant to be interactive, other than timeout you should try tail -100 (100 or whatever) to catch last lines. main part would be tail -100 /whatever/sample.log | gzip > /whatever/sample.log.gz


1

Using GNU grep and printf: grep -F $(printf '%s\n' "${clipnumbers[@]}") clip?????-randomlongstring.png Which can be assigned to an array like so: files=($(grep -F $(printf '%s\n' "${clipnumbers[@]}") clip?????-randomlongstring.png))


1

What your looking for is ssh keys, then you wont have to type a password. To generate RSA keys, on the command line, enter: ssh-keygen -o -b 4096 -t rsa NOTE THIS: If you don't password-protect your private key, anyone with access to your computer conceivably can SSH (without being prompted for a password) to your account on any remote system that has the ...


1

There are several ways to do this, but I recommend using public/private keys rather than passing the password (which is possible). There are many other answers on this - but here is a quick how to: On the machine you are logging in from: Create a public/private key combination: ssh-keygen -t rsa Copy the public key to the remote machine: ssh-copy-id pi@...


1

I think this may be one of the (rare) cases when it actually makes sense to put the loop outside of Awk: $ for ((i=-4;i<=4;i+=2)); do awk -v i="$i" '{$1+=i} 1' Input; done 0 5 6 3 8 9 2 5 6 5 8 9 4 5 6 7 8 9 6 5 6 9 8 9 8 5 6 11 8 9 Otherwise: $ awk '{a[NR] = $1; b[NR] = $2 FS $3} END{for(i=-4;i<=4;i+=2){for(j=1;j<=NR;j++) print a[j]+i, b[j]}}' ...


1

Use read to ask for confirmation, e.g. like this: echo "fd $f file found..." read -p "Press enter to continue or Ctrl+c to cancel" cp -v "$f" "$1" or echo "fd $f file found..." read -p "Do you want to recover this file? [Yes/No] " confirmation [[ $confirmation =~ ^[YyJj] ]] || { echo "Canceled"; exit } cp -v "$f" "$1"


1

In zsh: files=( **/*.EXT(oe'{REPLY=$RANDOM}') ) first=(input3.EXT input5.EXT) printf 'file %s\n' ${first[@]} ${files:|first} > list.txt The first line assigns an array of all the files you're looking for (recursively), but orders them randomly. The second line assigns an array of filenames that you'd like to have first in the resulting list. The ...


1

Use aria2c instead: aria2c --on-download-complete="/path/to/script" -i file so your script can be: #!/bin/bash notify-send "Finished: $3" $1 is the gid from aria2c. $2 is the number of files. $3 is the filename.


1

Your logic is correct, but I had to make a few modifications to get it working. Added a missing space after IFS (otherwise error) Changed the quoted "$line/*" to "$line"/* (otherwise sed: can't read 2/*: No such file or directory) Quoted $j (only for better style) Both the sed and the cat/echo version do what they should. #!/bin/bash input="dir1.txt" ...


1

To limit the sort field to the second column (and not from the second column to the end of the line), you have to specify the end position: $ sort -uk2,2 file WP_012456834.1 NO_GROUP bsui|NP_700181 8 -53 48.18 62 WP_021815427.1 OG5_128110 rbal|NP_868155 1 -55 50.72 53.2 WP_021815421.1 OG5_132922 deth|YP_182312 3 -07 42.35 81.7 ...


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