Hot answers tagged

35

<$()> would be valid bash syntax for commands that read from a file (< part) where file names are created using command substitution ($() part) that redirect output to some other file (> part). Example: $ echo text > FILE $ wc < "$(echo FILE)" > WC_OUT $ cat WC_OUT 1 1 5 However, in the answer you linked to <$()> is used in the ...


17

You don't actually need rename here, you can work around it: $ file=35554842200284685106000166550020003504201637715423.xml $ newname=$(sed -E 's/.*(.{48})/\1/'<<<"$file"); $ mv -v "$file" "$newname" renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'


15

Here is one using bash specific P.E. parameter expansion. file=35554842200284685106000166550020003504201637715423.xml Only mv for external tools mv -v "$file" "${file:6}" Output renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml' Keeping the last 48 chars would be. mv -v "$file" "${...


9

Using ed (the line-editor that sed and grep are derived from): printf '%s\n' '11m0' 'w bonjour2' 'q' | ed -s bonjour This applies the editing command 11m0 to the file which moves line 11 to before the first line. It then writes the resulting document to the file bonjour2 and quits. Alternatively: printf '%s\n' '11m0' ',p' 'Q' | ed -s bonjour >...


9

Your rename seems to be the useless one from util-linux. You'd want to make sure one of the perl-based variants is installed instead (sometimes called prename) if you want to use regular expressions. And then: rename -n 's:^\./\d+(?=\d{44}\.xml\Z)::' ./*.xml (here replacing your 48 characters, with 44 digits followed by .xml so as to be more specific). ...


8

Sourcing your .bashrc is not a good idea. You could create a .bash_alias file with your alias and then source that file in your script and use shopt something like: shopt -s expand_aliases source ~/.bash_alias Bash man page states: Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (...


7

In Bash, custom messages can be set with MAILPATH. The man page has this example: MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"' Trying it: $ export MAILPATH="$MAIL?\"Santa was here.\"" $ $ $ $ "Santa was here." Oh, uh, okay. Must have misread the man page there. bright color would be great So we have to smuggle us some color ...


5

[ is a normal command (although a builtin) and the closing ] is just an argument to it. So is "$STR1"="$STR2" after the variables are expanded and quotes removed. The point is "$STR1"="$STR2" becomes one argument, and where there is just one argument before ] and it's a non-empty string, the result is true (exit status 0). You want [ "$STR1" = "$STR2" ] ...


5

Why oh why doesn't find find anything??? Drop 2>/dev/null and see the error. It will be: find: paths must precede expression: NetworkManager-wait-online.service -name needs exactly one argument, you're providing three. The first one is accepted. The second one is not recognized as a valid part of an expression, so find assumes it's a path, (like / you ...


4

You need to put the cd command inside the loop. The gotcha is that your paths are relative to your current directory, so the working directory must be reset back to the starting point at the beginning of each iteration in order for cd to work with your relative path. The ( ... ) subshell does that for us (the directory change lasts only for the scope of the ...


4

If you add the -i option to your hashbang(s) it will specify that the script runs in interactive mode. #!/bin/bash -i Alternatively you could call the scripts with that option: bash -i /path/to/script.sh


3

You could use eval here (standard): eval "RESULT=\$${X}_${Y}_NAME" Or the bash-specific: varname=${X}_${Y}_NAME RESULT=${!varname} And then: printf '%s\n' "$RESULT" remember echo can't be used to output arbitrary data, and parameter expansions must be quoted when in list contexts.


3

Not sure why I'm getting permission denied error. Apparently ${outputdir} expands to an empty string (the variable is not defined or empty) and ${state} expands to OR. This way ${outputdir}/${state}_595.txt expands to /OR_595.txt. /OR_595.txt points to a file named OR_595.txt in the root directory /. This file probably doesn't exist. It's normal a regular ...


3

Use a function. command1(){ convert -size 2000x1000 xc:none -gravity center \ -stroke yellow -pointsize 50 -font Courier-BoldOblique -strokewidth 3 -annotate +100+100 "${caption}" \ -blur 0x25 -level 0%,50% \ -fill white -stroke none -annotate +100+100 "${caption}" \ in.jpeg +swap -gravity center -geometry +0-3 \ -composite out....


3

First, this won't work the moment you have whitespace or literal glob characters in the arguments: command1="convert ... -fill white -stroke none -annotate +100+100 "${caption}" ... Note how even the syntax highlighting shows that the ${caption} part is not quoted. Quotes don't work inside quotes, i.e. quotes expanded from a parameter are literal, they don'...


3

If I understand correctly, you just want to move the 11th line to the first line. So if your original looked like Original line 1 Original line 2 ... Original line 18 Original line 19 Original line 20 Then the result would be Original line 11 Original line 1 Original line 2 ... Original line 9 Original line 10 Original line 12 Original line 13 ... ...


3

sed -n '1h;2,10H;11G;11,$p' First line, copy h because of new line, then append H until 10. At line 11, get the hold space From 11 to end, print. ]# sed -n '1h;2,10H;11G;11,$p' bonj French: Bonjour English: Hello Turkish: Marhaba Italian: Ciao German: Hallo Spanish: Hola Latin: Salve Greek: chai-ray Welsh: Helo Finnish: Hei Breton: Demat ...


3

Has anyone seen anything like this? Yes. To reproduce: Run echo foo. Run echo bar. ↑↑ so echo foo appears (or Ctrl+rfoo, so echo foo appears, then hold → to get to the end of the line). Hold Backspace, turn echo foo into an empty line, do not execute. ↓, so echo bar appears. Enter to execute echo bar again. Then ...


3

file=35554842200284685106000166550020003504201637715423.xml rename "s/"$file"/"${file: -48}"/" *.xml rename --version: /usr/bin/rename using File::Rename version 1.10


3

inotifywait emits a continuous set of events on the watched directory, so the recommended way would to move the watch out of the while loop and look for events within a new loop that looks on the output of the inotify. Note that this involves removing the --quiet flag, because the read command needs to see those events and read it over standard input. ...


3

Your files variable is an array and $files expands to the first element as you have noticed. To execute chmod on all elements of the array, use chmod +x "${files[@]}"


2

You can use a couple of translations: tr "'"'\#$%.,:;?!&*|()[]"<>=-' ' ' <SomeFile | tr -s '[:space:]' "\n" The first operation converts any of the characters you don't want into a space. The second operation converts all whitspace (including newlines) into a newline, squeezing runs of newlines to a single character.


2

#!/bin/sh for file in *; do mkdir "${file%.*}" done The ${file%.*} construct removes the extension. This is quite short, you could use it as one-liner: for file in *; do mkdir "${file%.*}"; done


2

Your first example will do what you want. Your second example won't do anything useful because you haven't got a command. If you are trying to represent the redirection of stdin in a command such as cat <file so that the error generated when file doesn't exist is hidden, you have a few choices; here are three [ -f file ] && cat <file ...


2

Just change the order and do the redirection of stderr to /dev/null FIRST: %% <file.txt 2>/dev/null bash: file.txt: No such file or directory %% 2>/dev/null <file.txt %% Keep in mind that redirections are always performed from left to right; the idea is to have the stderr already redicted when the failing redirection is performed. However, ...


2

I think that that setting is supposed to improve the user experience, not the "performance". It should save you from having to run hash -r by hand when you moved or removed an executable. Compare: bash$ mkdir -p first second; PATH=$PATH:first:second bash$ echo echo ok > first/ok; chmod 755 first/ok bash$ ok ok bash$ mv first/ok second/ok bash$ ok bash: ...


2

In bash you use globstar shell option. #!/usr/bin/env bash shopt -s globstar for d in Main/**/*.tex; do echo pdflatex "$d" done Or use find. find Main/ -type f -name '*.tex' -exec sh -c 'echo pdflatex "$@"' _ {} + Remove the echo once you're satisfied with the result.


2

You can assign the output to a variable, then you can use pattern matching, for example: VAR1=ABCD01 echo ${VAR1##*[[:alpha:]]} This will remove all alphabetical characters from the variable and will print "01".


2

After posting my original answer below, I realized now that having an array was overkill and all you really need is: awk ' NR < 11 { buf = buf $0 ORS; next } { print printf "%s", buf buf = "" } ' file > new_file e.g.: $ seq 15 | awk ' NR < 11 { buf = buf $0 ORS; next } { print printf "%s", buf buf = "" } ' 11 1 2 3 4 5 6 7 ...


2

Something like this. for f in /mnt/usb/Convert/2020-02-24-16-13.h264; do echo MP4Box -add "$f" "${f%.*}.mp4" done output MP4Box -add /mnt/usb/Convert/2020-02-24-16-13.h264 /mnt/usb/Convert/2020-02-24-16-13.mp4 If you have a lot of files ending in *.h264 for f in /mnt/usb/Convert/*.h264; do echo MP4Box -add "$f" "${f%.*}.mp4" done If you're inside ...


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