我想使用命令行程序(特别是地质科学) 接受 file_a.tif 和 file_a.tfw 并输出 file_b.tif。基本上,它将两个同名但具有不同文件扩展名的文件组合起来并输出新文件。我想弄清楚如何批量处理几千个这样的文件。我已经使用基本ls > output
命令创建了所有这些文件的列表。
我不一定在寻找针对此程序的答案,而是更多地在寻找一般的脚本。
我也不指望你为我写这个,请给我一个大致的方向。
谢谢你的帮助!
答案1
我倾向于使用 sed 或 awk 来构建命令行,然后将它们通过管道传输到 shell。举个可能的例子,如果你有一个只有 xxxxx_a.tif 文件名的文件,
sed -e 's/\(.*\)_.*/geotifcp \1_a.tif \1_a.tfw \1_b.tif/' < list-file.txt
看看它是否生成了你想要的命令,然后
sed -e 's/\(.*\)_.*/geotifcp \1_a.tif \1_a.tfw \1_b.tif/' < list-file.txt | sh
来运行它们全部。
假设输入文件名为和,输出名称为 ,输入行的asdfasdfsadf_a.tif
结果为。geotifcp asdfasdfsadf_a.tif asdfasdfsadf_a.tfw asdfasdfsadf_b.tif
[filename]_a.tif
[filename]_a.tiw
[filename]_b.tif
答案2
命令行参数
您可能想使用命令行参数。
尝试这个 Bash 脚本:
#!/bin/bash
echo "First argument is $1"
echo "Second argument is $2"
如果脚本文件名是test1.sh
,则将获得以下内容:
a@u1104:~$ chmod +x test1.sh
a@u1104:~$ ./test1.sh
First argument is
Second argument is
a@u1104:~$ ./test1.sh file1.tif file2.tiw
First argument is file1.tif
Second argument is file2.tiw
从文件中读取行
另一个组件是循环遍历文件。您可以这样做:
cat test |while read line; do
echo "${line}"
done
例如echo "${line}"
,你可以这样做./test1.sh ${line}.tif ${line}.tiw
答案3
我建议你看看
sed # to manipulate text output from, for instance, ls
和
xargs # to use some std input to generate (many) new command lines
与将一个命令的输出通过管道传输到下一个命令的输入相结合(例如从 ls 到 sed 到 xargs)
也就是说,假设您有一个包含 *tif 和 *tfw 文件的目录。您想使用相应的 tfw 文件对 tif 文件进行一些操作。我们还假设每个 tif 文件都有一个名称完全相同的 tfw 文件
# 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
后一行可能几乎可以在一个很长(难以阅读)的命令行中完成您需要做的事情,而无需脚本。
为了帮助理解,您还可以首先创建文件列表,如下所示:
ls *tif> output.list
然后用 sed 清理它以确保它运行良好。
sed -s 's/\.tif$//' output.list > clean_output.list
然后使用 xargs 和选项 -p 而不是 -t 来在发出每个命令之前获得提示:
cat clean_output.list | xargs -i -p geotifcp -e {}.tfw {}.tif geo_{}.tif
编辑:前者的一个变体是使用更多 sed 而不是更少 xargs。这也更易于“调试”。它确实需要您学习一些正则表达式(这是值得的)。
本质上,你可以用 sed 完全生成所需命令的文本
sed -s 's/\(.*\)\.tif$/geotifcp -e \1.tfw \1.tif geo_\1.tif/' output.list > process.sh
我知道,正则表达式看起来很糟糕,但是这里是单引号中内容的粗略解释:'s/A/B/'用 B 替换 A,在我们的例子中是 (something).tif(请注意,我们必须转义括号)something 存储在 \1 中并用于构建 geotifcp 命令(即 B)。