shell脚本,怎么用c实现?

sh/bash/dash/ksh/zsh等Shell脚本
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

shell脚本,怎么用c实现?

#1

帖子 naturalaw » 2012-07-01 18:17

在cygwin下,shell效率还是不行啊。只能将就用用了,现在想用c来重写。

有需求如下:
把第一列.jpg,重命名为第二列,以逗号分隔。

有tmp.txt如下
11,000010030.jpg
21,2000.jpg
221,90ew2000.jpg
有图片如下
11.jpg 21.jpg 221.jpg
有shell脚本如下
当然,shell的数组也是用过的,不过不在这个版本用,用它感觉也是慢。
用数组来存储新旧文件名。
[bash]#!/bin/bash
_dir=~/pic
if [ -f tmp.txt ];then {
[ $PWD == $_dir ] || cd $_dir
count=0
for var in *.jpg;do
page=${var%%.jpg};
fn=`sed -n "/^$page,/p" tmp.txt | awk -F',' '{print $2}'`;
mv $page.jpg $fn && count=`expr $count + 1`
done
echo "rename $count files ok"
}
else
echo -e "\nerror: tmp.txt does no exist\n"
fi
[/bash]
c源码如下,(求其正解)
[c]#include <stdio.h>
int main(void)
{
FILE *p = NULL;
int page;
int yh[4];
char img[20];
char mlbl[20];

if(p = fopen("file.txt", "r"))
{
int rows=0;
while(!feof(p))
{
fscanf(p, "%d,%s\n", &page, img);
printf("\n%d\t%s\n", page, img);


char oldname[80], newname[80];
/* prompt for file to rename and new name
oldname=page;
newname=img;
printf("File to rename: ");
gets(oldname);
printf("New name: ");
gets(newname);*/

/* Rename the file
if (rename(oldname, newname) == 0)
printf("Renamed %s to %s./n", oldname, newname);
else
perror("rename");

return 0;*/
rows++;
}
fclose(p);
}
return 0;
}
[/c]

刚刚开始学c,没搞懂啊,不知道rename函数接受什么样的数据类型,类型转换失败!
上次由 naturalaw 在 2012-07-01 18:44,总共编辑 4 次。
  • The eternal law
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell脚本,怎么用c实现?

#2

帖子 eexpress » 2012-07-01 18:20

这样转c,很难受的。
shell的好处,就是常用的事情,都包裹好了。
何必转。
● 鸣学
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: shell脚本,怎么用c实现?

#3

帖子 cuihao » 2012-07-01 18:28

Windows就不是搞批处理的料,bat都慢死了。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#4

帖子 naturalaw » 2012-07-01 18:33

eexpress 写了:这样转c,很难受的。
shell的好处,就是常用的事情,都包裹好了。
何必转。
是想转一下,主要是cygwin的shell慢得有点折腾,虽然可以完成。
要么改进shell的效率(搞linux虚拟机)要么使用别的语言来实现,比如c/perl/python等。
  • The eternal law
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#5

帖子 naturalaw » 2012-07-01 18:35

cuihao 写了:Windows就不是搞批处理的料,bat都慢死了。
bs一下cmd.exe
  • The eternal law
niejieqiang
帖子: 151
注册时间: 2009-05-29 22:05

Re: shell脚本,怎么用c实现?

#6

帖子 niejieqiang » 2012-07-01 18:38

cuihao 写了:Windows就不是搞批处理的料,bat都慢死了。
那perl怎么在里面跑得飞快
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell脚本,怎么用c实现?

#7

帖子 eexpress » 2012-07-01 18:40

放弃这想法吧。2者的思路都不同。你要是逐条实现,那是一个大工程。
● 鸣学
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#8

帖子 naturalaw » 2012-07-01 19:02

eexpress 写了:放弃这想法吧。2者的思路都不同。你要是逐条实现,那是一个大工程。
只能搁着了,现在时间有点紧。
大工程,当练手了,没项目没动力啊。
  • The eternal law
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: shell脚本,怎么用c实现?

#9

帖子 lilydjwg » 2012-07-01 19:20

niejieqiang 写了:
cuihao 写了:Windows就不是搞批处理的料,bat都慢死了。
那perl怎么在里面跑得飞快
因为 Perl 只一个进程。Windows 创建进程比较慢,Cygwin 更是如此。
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: shell脚本,怎么用c实现?

#10

帖子 aerofox » 2012-07-01 20:00

还是先改改 shell 脚本再说吧。
首先说一下,你的脚本好像有个 bug:只有在当前目录下及 ~/pic 目录下都存在 tmp.txt 时,脚本才能正常执行。
然后是效率问题,一遍一遍的 sed、awk,效率自然不高,不如直接一遍 sed 或 awk 把 tmp.txt 改为一下脚本,第二遍则执行这个脚本,省去了循环。

[bash]#!/bin/bash
if [ -f tmp.txt ];then
sed '1s/\(.*\),/mv \1.jpg /' tmp.txt > tmp.sh
script_dir="$PWD"
cd ~/pic
sh $script_dir/tmp.sh
fi[/bash]
没计数,如果需要计数,改一改那条 sed 语句同样可以实现。
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#11

帖子 naturalaw » 2012-07-01 23:12

aerofox 写了:还是先改改 shell 脚本再说吧。
首先说一下,你的脚本好像有个 bug:只有在当前目录下及 ~/pic 目录下都存在 tmp.txt 时,脚本才能正常执行。
然后是效率问题,一遍一遍的 sed、awk,效率自然不高,不如直接一遍 sed 或 awk 把 tmp.txt 改为一下脚本,第二遍则执行这个脚本,省去了循环。

[bash]#!/bin/bash
if [ -f tmp.txt ];then
sed '1s/\(.*\),/mv \1.jpg /' tmp.txt > tmp.sh
script_dir="$PWD"
cd ~/pic
sh $script_dir/tmp.sh
fi[/bash]
没计数,如果需要计数,改一改那条 sed 语句同样可以实现。
谢谢指导。
tmp.txt必须有,且在当前工作目录~/pic,因为命名是靠它的。
  • The eternal law
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#12

帖子 naturalaw » 2012-07-02 1:06

做了一个改进,应该可以吧。
$ cat tmp.txt
1,200000.jpg,110111224
2,2022341.jpg,110111224
3,24324202.jpg,110111224
4,2042343.jpg,110111224
5,9023490204.jpg,110111224
6,20432425.jpg,110111224
7,24206.jpg,110111224
8,204327.jpg,110111224
9,242308.jpg,110111224

163 rows ok
[bash]#!/bin/bash
if [ -f tmp.txt ];then
echo "count=0" >tmp.sh
chah=`sed -n '1s/^.*,//p' tmp.txt`
sed '/rows/d;s/.\{10\}$//g;s/\(.*\),\(.*\)$/[ -f \1.jpg ] \&\& mv -v \1.jpg \2 \&\& count=`expr $count + 1`/' tmp.txt >> tmp.sh
echo -e "mv -v ????*.jpg /cygdrive/d/$chah\n"'echo rename $count files ok!' >>tmp.sh
script_dir="$PWD"
sh $script_dir/tmp.sh
fi
[/bash]
  • The eternal law
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: shell脚本,怎么用c实现?

#13

帖子 aerofox » 2012-07-02 6:33

不要那点多余的东西了,既然 tmp.txt 总是在 ~/pic 目录下,脚本也总是在 ~/pic 目录下执行,第一个脚本中无需 [ $PWD == $_dir ] || cd $_dir(或者把这条放到 if 前面去)。楼上的脚本中直接 sh ./tmp.sh 就是了。

另一个实现的途径是,使用 awk 的 system 函数。

代码: 全选

awk -F, 'NF==3 {system("mv " $1 ".jpg " $2)}'
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#14

帖子 naturalaw » 2012-07-02 21:31

aerofox 写了:不要那点多余的东西了,既然 tmp.txt 总是在 ~/pic 目录下,脚本也总是在 ~/pic 目录下执行,第一个脚本中无需 [ $PWD == $_dir ] || cd $_dir(或者把这条放到 if 前面去)。楼上的脚本中直接 sh ./tmp.sh 就是了。

另一个实现的途径是,使用 awk 的 system 函数。

代码: 全选

awk -F, 'NF==3 {system("mv " $1 ".jpg " $2)}'
学习了。
测试了一下, 计数器还是要用的。
[bash]touch {2..7}.jpg;
ls *jpg;
awk -F, 'BEGIN{count=0}NF==3{system("[ -f " $1".jpg ] && mv -v " $1".jpg " $2 ) || count++}END{print r"\n rename "count " files ok!"}' tmp.txt;
rm *jpg -v[/bash]
  • The eternal law
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell脚本,怎么用c实现?

#15

帖子 naturalaw » 2012-08-08 3:58

其实,perl更快。
[perl]#! /usr/bin/perl
use File::Copy;
open(FILES,"file.txt");
$l=0;
while(<FILES>){
if (/(.*?),(.*?),(.*?)$/){
$new="$3//$2";
move("$1.jpg","$new") && $l++;
}
}
printf("rename $l files ok.\n");

[/perl]
  • The eternal law
回复