Verwenden von Variablen aus einer Textdatei in Scripting


Ich möchte ein Befehlszeilenprogramm (speziell geotifcp) verwenden, das file_a.tif und file_a.tfw verwendet und file_b.tif ausgibt.Grundsätzlich werden zwei gleichnamige Dateien mit unterschiedlichen Dateierweiterungen kombiniert und die neue Datei ausgegeben.Ich möchte herausfinden, wie man ein paar tausend dieser Dinge herausholt.Ich habe Listen all dieser Dateien mit grundlegenden ls > output-Befehlen erstellt.
Ich suche nicht unbedingt nach einer Antwort für dieses Programm, sondern eher für Skripte im Allgemeinen.
Ich suche auch nicht, dass du das für mich schreibst, gib mir bitte einen Stoß in die allgemeine Richtung.

Vielen Dank für jede Hilfe!


Command line arguments

You probably what to use command line arguments.

Try this bash script:


echo "First argument is $1"
echo "Second argument is $2"

If the script file name is, then you'll have this:

[email protected]:~$ chmod +x 
[email protected]:~$ ./ 
First argument is 
Second argument is 
[email protected]:~$ ./ file1.tif file2.tiw
First argument is file1.tif
Second argument is file2.tiw

Reading lines from files

Another component would be to loop through your file. You can do it like this:

cat test |while read line; do 
  echo "${line}"

Instead of echo "${line}" you can, for example, do ./ ${line}.tif ${line}.tiw


I suggest you have a look at

sed # to manipulate text output from, for instance, ls


xargs # to use some std input to generate (many) new command lines

in combination with piping the output of one command into the input of the next (like from ls to sed to xargs)

To wit, say, you have a directory with *tif and *tfw file. You want to do something to the tif files using the corresponding tfw file. Let's also assume for every tif file there is a tfw file of the exact same name

# list all those tif files in one long column
ls -1 *.tif 

# chop of the end .*tif leaving you with the base name
ls *.tif | sed -s 's/\.tif$//'

# feed the previous into xargs to tag a tif with the info in a tfw and
# create new geo_*.tif file
ls *.tif | sed -s 's/\.tif$//' | xargs -i -t geotifcp -e {}.tfw {}.tif geo_{}.tif

The latter line might pretty much do what you need in one long (difficult to read) commandline without scripting.

To aid understanding you can also first create the file list as you did:

ls *tif> output.list

Then clean it up with sed to make sure it behaves well.

sed -s 's/\.tif$//' output.list > clean_output.list

end then use xargs with option -p instead of -t to get a prompt before the issuance of each command:

cat clean_output.list | xargs -i -p geotifcp -e {}.tfw {}.tif geo_{}.tif

EDIT: A variation on the former is to use more sed less xargs. This is also a bit more 'debuggable'. It does require you to learn a bit about regular expressions (which is well worth the effort).

Essentially, one can generate the text of your desired command entirely with sed

sed -s 's/\(.*\)\.tif$/geotifcp -e \1.tfw \1.tif geo_\1.tif/'  output.list >

I know, regex looks horrible but here is the rough explanation of the content in the single quotes: 's/A/B/' substitutes A with B A in our case is (something).tif (note that we have to escape the brackets) The something is stored in \1 and gets used to build the geotifcp command (which is B).


I tend to do stuff like this using sed or awk to build command lines, then pipe them to a shell. As a possible example, if you have a file of just the xxxxx_a.tif filenames,

sed -e 's/\(.*\)_.*/geotifcp \1_a.tif \1_a.tfw \1_b.tif/' < list-file.txt

to see if it's generating the commands you're after, then

sed -e 's/\(.*\)_.*/geotifcp \1_a.tif \1_a.tfw \1_b.tif/' < list-file.txt | sh

to run them all.

An input line of asdfasdfsadf_a.tif results in geotifcp asdfasdfsadf_a.tif asdfasdfsadf_a.tfw asdfasdfsadf_b.tif, assuming that the input filenames are [filename]_a.tif and [filename]_a.tiw and the output name [filename]_b.tif.