免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4305 | 回复: 10

[文本处理] 请教个shell for in使用问题 [复制链接]

论坛徽章:
0
发表于 2018-04-03 16:41 |显示全部楼层
本帖最后由 cheungjan 于 2018-04-03 16:43 编辑

在网上看到有个awk循环读取文件内容,并把字段赋给相应的变量的文章
其中 :
文本文件id_num.txt 内容如下0001 1
0002 2
0003 3
0004 4


编写脚本awk_each_line.sh内容如下
#!/bin/bash

i=1
for ID in $(cat id_num.txt)
do
        NUM=$i
        S_ID=$(awk 'NR=='$NUM' {print $1}' id_num.txt)
        T_NUM=$(awk 'NR=='$NUM' {print $2}' id_num.txt)
        echo $S_ID
        echo $T_NUM
        : $((i++))
done


编译运行后如下

微信截图_20180403162900.png
然后我在此代码上加了个echo $NUM一行
#!/bin/bash

i=1
for ID in $(cat id_num.txt)
do
        NUM=$i
        S_ID=$(awk 'NR=='$NUM' {print $1}' id_num.txt)
        T_NUM=$(awk 'NR=='$NUM' {print $2}' id_num.txt)
        echo $NUM
        echo $S_ID
        echo $T_NUM
        : $((i++))
done

运行结果则变成
微信截图_20180403163131.png
请问大神,这个NUM变量echo显示为什么会多了5,6,7,8,不应该只是1,2,3,4吗


PS:

主要是我想在此代码修改用来根据读取文本所参数当做拷贝目标文件的目录然后通过cp目录将文件拷贝到对应的目录下面,结果还是和上面类似错误,虽然拷贝成功了读取的文本目录里的参数对应路径,但是多出来一边的错误提示。

[root@iZ11ga0biv4Z cj]# cat tawk1126
#!/bin/bash

i=1
for ID in $(cat test1126.txt)
do
        NUM=$i
        STORE_CODE=$(awk 'NR=='$NUM' {print $1}' test1126.txt)
        COMPANY_CODE=$(awk 'NR=='$NUM' {print $2}' test1126.txt)
        cp -f /home/test/test1.zip /home/test/$COMPANY_CODE/$STORE_CODE/download/
        sleep 1
         cp -f /home/test/test2.zip /home/test/$COMPANY_CODE/$STORE_CODE/download/        
        echo $STORE_CODE
        echo $COMPANY_CODE
        : $((i++))
done


[root@iZ11ga0biv4Z cj]# cat test1126.txt
20000001        st
20000002        st
00000001        tt
00000002        tt
10000001        tt


[root@iZ11ga0biv4Z cj]# ./tawk1126
20000001
st
20000002
st
00000001
tt
00000002
tt
10000001
tt
cp: 无法创建普通文件"/home/test///download/": 不是目录
cp: 无法创建普通文件"/home/test///download/": 不是目录


cp: 无法创建普通文件"/home/test///download/": 不是目录
cp: 无法创建普通文件"/home/test///download/": 不是目录


cp: 无法创建普通文件"/home/test///download/": 不是目录
cp: 无法创建普通文件"/home/test///download/": 不是目录


cp: 无法创建普通文件"/home/test///download/": 不是目录
cp: 无法创建普通文件"/home/test///download/": 不是目录


cp: 无法创建普通文件"/home/test///download/": 不是目录
cp: 无法创建普通文件"/home/test///download/": 不是目录



论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2018-04-03 17:02 |显示全部楼层
回复 1# cheungjan

use awk directly and easy to understand

$ cat test1126.txt
20000001        st
20000002        st
00000001        tt
00000002        tt
10000001        tt

$ awk '{print $1,$2}' test1126.txt
20000001 st
20000002 st
00000001 tt
00000002 tt
10000001 tt

$ awk '{print "$1="$1,"$2="$2}' test1126.txt
$1=20000001 $2=st
$1=20000002 $2=st
$1=00000001 $2=tt
$1=00000002 $2=tt
$1=10000001 $2=tt

论坛徽章:
0
发表于 2018-04-03 19:20 |显示全部楼层
回复 2# jason680

我的意思是将这每行的两个字段作为两个变量参数,提供到后续我调用语句里做参数引用。
大侠,这个语句只是一次显示完所有打印值吧

论坛徽章:
0
发表于 2018-04-03 19:45 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2018-04-03 20:20 |显示全部楼层
回复 3# cheungjan

1. input file/data
2. procedure rule
3. output file/data
don't forget the example
Note: easy to know and clear

论坛徽章:
6
程序设计版块每日发帖之星
日期:2016-05-11 06:20:00操作系统版块每日发帖之星
日期:2016-05-12 06:20:00每日论坛发贴之星
日期:2016-05-12 06:20:00操作系统版块每日发帖之星
日期:2016-05-14 06:20:00程序设计版块每日发帖之星
日期:2016-05-31 06:20:00每日论坛发贴之星
日期:2016-05-31 06:20:00
发表于 2018-04-03 20:47 |显示全部楼层
本帖最后由 1cpuer 于 2018-04-03 22:21 编辑

回复 1# cheungjan
cp 命令没有发现$COMPANY_CODE/$STORE_CODE 的目录
在 cp 之前 mkdir # 建立一个

$COMPANY_CODE/$STORE_CODE
20000001        st

awk 'NR=='$NUM' {print $1}' id_num.txt  ## 单独运行 terminal 可能不行;但 shell 中运行可行。

上面是shell 调用 awk 变量
当然亦有awk 调用 shell 变量
$(awk 'NR=='$NUM' {print $1}' id_num.txt)


# [ /home/soio/1bs/awks ] {2018-04-03 20:23:49}
: 1522758229:0;➜  awk 'NR="$NUM" {print $NUM}' id_num.txt
0001 1
0002 2
0003 3
0004 4

######
12345678
0001
1
0002
2
0003
3
0004
4

8行

论坛徽章:
25
程序设计版块每日发帖之星
日期:2016-05-03 06:20:0015-16赛季CBA联赛之八一
日期:2018-07-05 10:34:09黑曼巴
日期:2018-07-06 15:19:5015-16赛季CBA联赛之佛山
日期:2018-08-03 13:19:3315-16赛季CBA联赛之山西
日期:2018-08-07 19:46:2315-16赛季CBA联赛之广夏
日期:2018-08-08 19:31:5015-16赛季CBA联赛之青岛
日期:2018-11-26 15:21:5015-16赛季CBA联赛之上海
日期:2018-12-11 09:45:3219周年集字徽章-年
日期:2020-04-18 23:54:5215-16赛季CBA联赛之深圳
日期:2020-04-19 21:40:19黑曼巴
日期:2022-04-03 17:55:1315-16赛季CBA联赛之八一
日期:2018-07-03 16:56:46
发表于 2018-04-04 09:32 |显示全部楼层
本帖最后由 wh7211 于 2018-04-04 09:33 编辑

回复 1# cheungjan


请问大神,这个NUM变量echo显示为什么会多了5,6,7,8,不应该只是1,2,3,4吗

因为『for ID in $(cat id_num.txt)』中,in后面的参数值是『0001 1 0002 2 0003 3 0004 4』,循环了8次,因此会多出了5,6,7,8。可以参考下面代码实现你的需求:
  1. #!/bin/bash
  2. while read STORE_CODE COMPANY_CODE
  3. do
  4. echo "${COMPANY_CODE}|${STORE_CODE}"
  5. cp -f /home/test/test1.zip /home/test/test2.zip /home/test/${COMPANY_CODE}/${STORE_CODE}/download/
  6. done<"test1126.txt"
复制代码


评分

参与人数 1信誉积分 +10 收起 理由
cheungjan + 10 很给力!

查看全部评分

论坛徽章:
0
发表于 2018-04-04 10:19 |显示全部楼层
1cpuer 发表于 2018-04-03 20:47
回复 1# cheungjan
cp 命令没有发现$COMPANY_CODE/$STORE_CODE 的目录
在 cp 之前 mkdir # 建立一个

cp 命令没有发现$COMPANY_CODE/$STORE_CODE 的目录
在 cp 之前 mkdir # 建立一个


这个是有对应目录的,对应cp也成功了,拷贝成功后但是又多出来一些错误提示,对应我用的ssh登录的云平台测试的(对应是shell方式)




运行结果txt文本里五行记录都执行成功,但是NUM的值又循环了五次,这后面循环了五次对应NUM变成了6,7,8,9,10,实际txt里就五行数据(每行两个数据通过空格间隔)以NUM一到五循环执行的是提取文本里五行的数字做$COMPANY_CODE和$STORE_CODE变量值给调用然后给cp做参数。

论坛徽章:
0
发表于 2018-04-04 11:01 |显示全部楼层
回复 7# wh7211

谢谢大神解惑for读取我一直以为是根据行数循环的,没想到还很每行里几列内容(空格符隔开)有关系,在原来的文本有多加一列,果然NUM值又增加了

那如果用for in处理这种多行数据,每行有好几列内容,那对应有没有改善的方式去实现效果,个人一直认为for和while两个函数都能相互替代使用的

论坛徽章:
6
程序设计版块每日发帖之星
日期:2016-05-11 06:20:00操作系统版块每日发帖之星
日期:2016-05-12 06:20:00每日论坛发贴之星
日期:2016-05-12 06:20:00操作系统版块每日发帖之星
日期:2016-05-14 06:20:00程序设计版块每日发帖之星
日期:2016-05-31 06:20:00每日论坛发贴之星
日期:2016-05-31 06:20:00
发表于 2018-04-04 11:09 |显示全部楼层
本帖最后由 1cpuer 于 2018-04-04 11:38 编辑

回复 8# cheungjan

        echo $NUM
        echo $S_ID
        echo $T_NUM
        : $((i++))


6,7,8,9,10 问题就是打印变量

$NUM 好像就是 $S_ID + $T_NUM 的行数
相当与 awk : FNR
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP