Tag Info

Hot answers tagged

15

You don't use ./ to run a script in general, you use it to run a program (script or compiled binary) in the current directory.  If the second script is in /path/pycharm.sh, then you should run it as /path/pycharm.sh, and not ./pycharm.sh.


15

$ echo "this_is_the_string" | sed -r 's/(^|_)([a-z])/\U\2/g' ThisIsTheString Substitute pattern (^|_) at the start of the string or after an underscore - first group ([a-z]) single lower case letter - second group by \U\2 uppercasing second group g globally.


8

The function-based approach results in the clearest code. There's at least two variants possible, the one suggested by FloHimself above in the comment (which would not be my preferred way): function myprint { if type banner >/dev/null then banner "$@" else echo "$@" fi } myprint "Hello World!" or - the variant I'd prefer - to use a ...


5

You've got this code: for file in *.mkv *avi *mp4 *flv *ogg *mov; do target="${file%.*}.mkv" ffmpeg -i "$file" "$target" && rm -rf "$file" done which runs in the current directory. To turn it into a recursive process you have a couple of choices. The easiest (IMO) is to use find as you suggested. The syntax for find is very "un-UNIX-like" ...


5

It is not necessary to represent the entire string in a regular expression match -- sed has the /g modifier that allows you to walk over multiple matches and replace each of them: echo "this_is_the_string" | sed 's/_\([a-z]\)/\U\1/g;s/^\([a-z]\)/\U\1/g' The first regex is _\([a-z]\) -- each letter after underscore; the second one matches the first letter ...


5

Your shell script is in another directory, use the absolute path. sh /path/pycharm.sh


4

The error is fairly explicit: It either doesn't exist at the specified path, or It doesn't have the permission to open it. As you're using a relative path, I'd put my money on the first. Specify a full path to your second pycharm.sh and it should work.


4

You wrote *.{mkv} instead of *.mkv. Therefore the loop will only loop about the one "file" *.{mkv} which does not exist. In this case the output of mediainfo is simply empty. Add something like echo "$file" in your loop to verify.


4

Oh dear, triple ssh pipeline with a loop and useless xargs, you found the worst way of doing this. The \r you are seeing appears to be a leftover of the newline that is getting across the pipeline. You should remove the -t option, it may be the cause of your problems. Output meant to display in virtual terminals is different from the normal stream. ...


4

To edit file in-place with OSX sed, you need to set empty extension: $ sed -i '' '1i\ #encoding:utf-8' filename And you need a literal newline after i\. This is specified by POSIX sed. Only GNU sed allows text to be inserted on the same line with command. sed can also works with multiple files at once, so you can use -exec command {} + form: $ find . ...


3

Example snippet without piping (assumes you are giving the path as argument): #!/bin/bash backup_dir=/backup/ OIFS="$IFS" IFS=$'\n' files="$(find "$1" -type f -name '*.mkv' -or -name '*.avi' -or -name '*.mp4' -or -name '*.ogg' -or -name '*.mov' -or -name '*.flv')" for f in $files; do # get path d="${f%/*}" # get filename b="$(basename ...


3

With POSIX find: find . \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o \ -name '*ogg' -o -name '*mov' \) -exec sh -c ' for file do target="${file%.*}.mkv" echo ffmpeg -i "$file" "$target" done' sh {} + Replace echo with whatever command you want to use. If you have GNU find or BSD find, you can use -regex: find ...


3

There is no way to achieve this within a script - scripts start subshell, which is a standalone environment. There's all sorts of reasons for this, but pretty fundamentally - a script cannot tamper with your environment (including your cwd). The closest you get is creating an alias within the current shell. alias chr="cd /" Either that, or 'source' the ...


3

Since you're using bash, if you stored your string in a variable you could also do it shell-only: uscore="this_is_the_string_to_be_converted" arr=(${uscore//_/ }) printf %s "${arr[@]^}" ThisIsTheStringToBeConverted ${uscore//_/ } replaces all _ with space, (....) splits the string into an array, ${arr[@]^} converts the first letter of each element to ...


3

Using Awk's output record separator, ORS: awk 'BEGIN{ORS=",";}1' infile


3

There's already a solution based on paste in the comment above. But if you prefer awk, here's an awk-solution: awk 'BEGIN{RS="";OFS=","};$1=$1' It doesn't create a spurious comma at the end and properly terminates the output by a newline.


3

Bjorn's solution seems like it should work, but another possibility would be to use find with a regex like find -regextype posix-extended -regex '.*/[[:digit:]]{1,}(-[[:digit:]]{1,}){4}$' then you can use that with either a -exec mv {} first-class \; or pipe to xargs or similar


3

With some shells, you could use extended globbing+certain flags to match only files in class one. With bash: shopt -s extglob for one in +([0-9])-+([0-9])-+([0-9])-+([0-9])-+([0-9]) do [[ -f $one ]] && mv -- "$one" first-class done +(<PATTERN>) matches one or more occurrences of the given pattern, [[ -f ... ]] tests for ...


3

The join utility is intended for exactly this kind of problem: it joins two files based on one of their fields, by default the first one. The files should be sorted first; so join <(sort file2) <(sort file1) | column -t produces Alice Wednesday 616.556.4458 Bob Tuesday 313.123.4567 Carol Monday 248.344.5576 Dave Thursday ...


2

Remove the '{}' from in the 'for file' part. It should be like this instead: for file in *.mkv; do height=$(mediainfo "$file" | grep -E 'Height'); echo $height; height=${height//[!0-9]/}; echo $height; done In your code the "*.{mkv}" is expanding to all files ending in '.{mkv}' of which, I presume, there aren't any, so the list in the for statement comes ...


2

The curl command is executed but its output is not assigned to num_redirect. This means that the output of curl is shown, i.e. "3" (without a newline). However, a newline is inserted when echo $num_redirect is run, as the variable is empty. This gives you the impression that the variable num_redirect has the value of "3". You should either use backticks or ...


2

You forgot this line: shopt -s expand_aliases e.g. #!/bin/bash shopt -s expand_aliases alias grep='grep -n' out=$(grep word "$1") echo "$out"


2

You don't need to recursively enumerate directories to delete them with rm -rf; you can simply list the top-level directories you want to delete. To determine whether a directory entry is a directory rather than a file, you can use find's -type d test; using . isn't a good indicator. The following should work for you: find * -maxdepth 0 ! -name encoded ...


2

I only put in this answer because it is shorter and simpler than any other so far. sed -re "s~(^|_)(.)~\U\2~g" It says: upcase, the character following a _ or the start. Non letters will not be changed, as they have no case.


2

In CentOS7, you have systemctl that will pretty much do most of this for you. If Apache is installed via the standard packages, this should work for you out-of-the-box: echo -n $(date +"%s %F %T"): \ if systemctl is-active httpd; then \ systemctl stop httpd && echo "httpd stopped"; \ elif systemctl enable httpd; then \ systemctl start httpd ...


2

If your bc calculations are somewhat involved, you could also use HERE docs to make it more readable: var2=500 bc << EOF scale=2 $var2 + 100 EOF prints out 600


2

Firstly, this is a UUOC (useless use of cat). There is no good eason to use cat here, sed is perfectly able to read files itself, and even if it wasn't, then redirecting standard input from the file would be equivalent to piping it. esc=$(echo -e '\e') sed "s,\(.*\) \(.*\) \(.*\) \(.*\),$esc[31m\1 $esc[34m\2 $esc[33m\3 $esc[32m\4$esc[m," file4 This ...


2

The simplest way is to just run command1 "hello world" || command2 "hello world" If the first command doesn't exist, the left hand side of the || wil fail so the command on the right will be run. I don't see why you need to test first. Just do, and if you fail, do something else. You can make that slightly better by ignoring error messages cause by a ...


2

If you want to use getopts (noted the "s") to get the command line arguments you can do something like while getopts "i:n:e:" OPT; do case "$OPT" in i) # do stuff with the i option ID="$OPTARG" ;; n) # do stuff with the n option ;; e) # do stuff with the e ...


2

The command cp -f * /var/www/ copies files matching * in the caller's current directory, i.e. your current directory. It is irrelevant where the script is located.



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