26

Yes, in the case when IFS is unset, restoring the value from $saved_IFS would actually set the value of IFS (to an empty value). This would affect the way field splitting of unquoted expansions is done, it would affect field splitting for the read built-in utility, and it would affect the way the positional parameters are combined into a string when using &...


10

Expansions don't get recursively applied. Doing that would make it impossible to handle arbitrary data with dollar signs embedded. (A related matter is that quotes and redirection and other operators are also just regular characters after expansions.) A somewhat usual custom is to have config files like that as actual shell script, so (like the ones in ...


9

If you're using bash you can use an array for this #!/bin/bash files=('foo bar' 'another file' file1 'file2') for f in "${files[@]}"; do file -- "$f"; done Quoting is required for file names containing whitespace; it's optional (but I'd recommend it) for plain file names. If the list of files comes from the current directory you can use ...


7

Sound like you want a variable whose contents is dynamically generated. bash does not have support for ksh93's disciplines, or zsh's dynamic named directory or mksh's value substitution which would make it easier, but you could use this kind of hack, using namerefs: var_generator() { date --iso-8601=ns; } var_history=() typeset -n var='var_history[ ${##${...


6

Inside a bash function, you can use local IFS=$'\n' or whatever to shadow the global (or parent function's local) value of IFS while inside the scope of this function. Further assignment to IFS will still be modifying your local version. In bash, It is an error to use local when not within a function. So this doesn't help if you're not writing a function, ...


5

If you have an empty line, using IFS won't work, because multiple \n are squeezed. However, you can use readarray: readarray -t arr < <(python init.py) echo "A='${arr[0]}', B='${arr[1]}', C='${arr[2]}', D='${arr[3]}'" Add -d '' to delimit by \0: readarray -d '' -t arr < <(python init.py) From man bash: -d The first character of ...


5

For your command line parsing, arrange with the pathname operands to always be the last ones on the command line: ./myscript -a -b -c -- 'foo bar' 'another file' file[12] The parsing of the options would look something like while getopts abc opt; do case $opt in a) a_opt=true ;; b) b_opt=true ;; c) c_opt=true ;; *) ...


4

The command compgen -v will display a list of names of shell variables in the current bash shell session. Also, declare -p, which lists the attributes and values of all variables in a form that is (almost always) suitable for shell input, does not list functions.


4

In sufficiently old shells, unset either doesn't exist at all or is unusably buggy (comments in Autoconf's source code say that unset IFS may crash the process). Kusalananda's answer cannot be used with such shells. If you have to worry about shells this old, your best bet is to set IFS to a space, a tab, and a newline, in that order, as early as possible: # ...


3

In Bash, I'd do it this way: [ -v IFS ] && oldIFS="$IFS" || unset oldIFS IFS=something some commands [ -v oldIFS ] && IFS="$oldIFS" || unset IFS or this way: [ "${IFS+set}" ] && oldIFS="$IFS" || unset oldIFS IFS=something some commands [ "${oldIFS+set}" ] && IFS="$...


3

That is a needlessly complicated way of getting what you're after! All you need is (I also changed to lower case variable names, please avoid using CAPS for shell script variables since those are used for environment variables and this can lead to name collisions) : testvar="$(grep -oP '^DIR\s*=\s*"\K[^"]+' /home/user/path/to/file.conf)" ...


3

There's a bit of a difference between the four script invocations you posted. ./script.sh -i "'foo bar' 'another file'" ./script.sh -i "foo\ bar another\ file" The above two both pass to the script -i as the first argument, and a single string as the second. In the first one, that's 'foo bar' 'another file', and in the second, it's foo\ ...


2

You were almost there, the thing you missed was the use of the bash's indirection operator ${!varname} which will ouput the value of the variable held in varname. Also, the canonical | right way, to use shell variables in awk code is via the -v awkvar=shell_data , rather than plugging them directly in an awk statement. file4=formatedFile1 file5=...


2

I think you have a misconception about how Linux environment variables work. Environment variables for a running shell are only defined for that instance of the shell that is running. They have no meaning or relevance outside of that. If you change the $PATH variable in a shell you are using, that change will only have an effect on that instance of the shell,...


1

filename=$(unzip toto.zip | awk 'sub(/^[[:space:]]*inflating:[[:space:]]+/,""){print; exit}') should work robustly and efficiently using any awk (but is untested). Also consider doing similar with the output of unzip -l.


1

This should work (although sometimes, there are differences between versions of sed and unzip available from one system to another): filename=$(unzip toto.zip | sed -n 's/^[[:space:]]*inflating:[[:space:]]*//p') This command unzips the file and send the output to sed. sed looks for lines starting with whitespace and then inflating: . If such a line is found,...


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