I don't know how to execute a command with a variable and get the result of this.
I have many .h
and .c
files and I need convert each from ISO-8859 to UTF-8.
So I make:
ls | grep "\.[ch]" | xargs myscript.sh
And in my script, the filename is in variable $1
. Now I need to perform
iconv -f ISO-8859 -t UTF-8 $1
and store result of this, because iconv
prints to stdout.
result=`iconv -f ISO-8859 -t UTF-8 $1`
echo $result
This seems to be not working, because it gives me some mismatch instead of converted $1
.
To store the output of a command in a variable, you can use the shell command substitution feature in the forms below: variable_name=$(command) variable_name=$(command [option ...] arg1 arg2 ...) OR variable_name='command' variable_name='command [option ...]
Executing programs from a script. When the program being executed is a shell script, bash will create a new bash process using a fork. This subshell reads the lines from the shell script one line at a time. Commands on each line are read, interpreted and executed as if they would have come directly from the keyboard.
Using variable from command line or terminal You don't have to use any special character before the variable name at the time of setting value in BASH like other programming languages. But you have to use '$' symbol before the variable name when you want to read data from the variable.
To get get result of command you need to use command substitution (bash feature). Command substitution provides executing a bash command/commands and store its output to variable. You can use special backticks (``). Everything what you write between backticks is executed by the shell before main command is executed.
If you need to do some kind of transformation on the data first, you can "capture" output with the following syntax:
result="$(iconv -f ISO-8859 -t UTF-8 $1)"
There is a gotcha here as well: if you are going to be storing large amounts of data with potential whitespace or other meddlesome characters in it, be sure to always quote the variable ("$result"
instead of $result
) to ensure it gets treated as a single string.
I'd do as such:
while read filename;
do
mv "$filename" "$filename.bck" && \
iconv -f ISO-8859 -t UTF-8 "$filename.bck" > "$filename"
done < find -iname '*.[hc]'
This creates backups on the fly and also handles files with whitespace (not newline characters).
Here is a solution that even handles newlines:
find -name '*.[ch]' \
-exec mv '{}' '{}.backup' \; \
-exec iconv -f ISO-8859 -t UTF-8 '{}.backup' -o '{}' \;
Generally, never parse filenames if you are going to use the results. The only sane ways I know of are
for file in ./*.[ch] ; do echo "$file" ; done
. Only works for one directory.-exec
-print0
(which prints the filenames as \0-separated strings) and use the output to build commandlines with xargs -0
and probably a helper script. This is quite cumbersome, though.Also, make sure that relative filenames you use are prefixed with ./
. Calling mv -from -to
isn't safe, but mv ./-from ./-to
is, and does what you want. E.g. when globbing, go with ./*.c
rather than *.c
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With