Chinaunix

标题: [快解决了] awk 连续域的显示及单字符判断的问题 [打印本页]

作者: 惟吾无为    时间: 2011-06-20 19:33
标题: [快解决了] awk 连续域的显示及单字符判断的问题
本帖最后由 惟吾无为 于 2011-06-23 09:47 编辑

假设需要处理倒数第2个域, 怎样表示?
这个是为了判断倒数第2域是否为r, 如果是就替换成x.
我故意把数据写开些. 理想中的第1域或第2域可能有不定的空格, 但最后3域格式固定. 所以...
d         d      n   r   3
a s d    df f   t   r   2


第3至第9域(不一定是最后一个域)呢?
主要是为了处理ll的结果, 含有空格的文件名就不好办了.
ll "a b c"
-rw-r--r-- 1 root root 677888 Apr  5 22:12 a b c
若是链接, 就又不好办了
ll "c f G"
lrw-r--r-- 1 root root 677888 Apr  5 22:12 c f G -> a b c



顺便问下, 中文文件名截取的问题.
只显示前N或N-1(防止半个中文)个字节. locale无效, 编码gbk, 所以只得自行截取判断.
直接printf截会有半个中文. 自己的纯bash实现感觉有点慢.
希望实现awk依次按字节截取字串, 并判断截获的那1Byte是否属于ascii字符的方法.(不介意有更好的方案)
作者: lionfun    时间: 2011-06-20 19:56
这个比较有趣,求解!
作者: 南极雨    时间: 2011-06-20 20:55
本帖最后由 南极雨 于 2011-06-20 21:11 编辑

回复 1# 惟吾无为


    倒数第二个域:[root@localhost ~]# echo 'd         d      n   r   3
> a s d    df f   t   r   2' | awk '{print $(NF-1)}'
r
r

至于第三域到第九域和中文字符我就没什么好办法了...
第三域到第九域可以在第二个域那里用sed 加入个回车,然后再取偶数行即可!
作者: 惟吾无为    时间: 2011-06-20 21:58
$(NF-1) 原来可以这样. 那些awk教程都没写...
作者: springwind426    时间: 2011-06-22 09:30
说说实际需求,也许会得到更好的解答

在正确的locale下,awk是可以截取指定长度的中文字符的

  1. ls | (LANG=GBK awk '{print substr($0,1,5);}' 会显示每个文件名的前5个字符
  2. ls | (LANG=POSIX awk '{print substr($0,1,5);}' 会显示每个文件名的前5个字节
复制代码

作者: 惟吾无为    时间: 2011-06-22 11:54
本帖最后由 惟吾无为 于 2011-06-22 11:56 编辑
说说实际需求,也许会得到更好的解答

在正确的locale下,awk是可以截取指定长度的中文字符的
springwind426 发表于 2011-06-22 09:30



    locale无效. 二者结果相同.

我想知道怎样在awk里实现
char=${string:start_position:charlength}   # 截取并赋值

if [[ "$char" == [^[:ascii:]] ]] ...   # 判断刚才截取的内容是否为ascii字符.
作者: yinyuemi    时间: 2011-06-22 12:00
回复 6# 惟吾无为


    substr + 正则匹配 试试
作者: 惟吾无为    时间: 2011-06-22 17:32
不会awk, 所以才发问的...

还有awk数组, 能不能直接表示所有内容. 像${arry[*]}. 而非for逐个显示内容.
作者: 267020090    时间: 2011-06-22 22:11
[root@jssweb awk]# awk '{print $(NF-1)}' 123 | awk '{a=$1;(a!~/1/) ? $1 : x ; print $1}'
1
3
4
4
4
r

思路有了 语法记不清了 擦
作者: 267020090    时间: 2011-06-22 22:22
[root@jssweb awk]# cat 123
Mary 12 1  33
mary 23 3  343
Maty 24 4  33
lucy 25 4  33
lily 25 4  33
lily 25 r  33


[root@jssweb awk]# awk '{print $(NF-1)}' 123 | awk '{a=($1!~/r/) ? $1 : "x" ; print a}'
1
3
4
4
4
x
作者: yinyuemi    时间: 2011-06-22 23:39
本帖最后由 yinyuemi 于 2011-06-23 02:54 编辑

回复 8# 惟吾无为


    大概意思:
  1. awk '{char=substr($(NF-1):start_position:charlength)}   # 截取并赋值
  2. {if (char ~ /[^[:ascii:]]/){action}}'   # 判断刚才截取的内容是否为ascii字符.

  3. awk 类似bash的${array[*]}的写法,一个参考的办法是在你创建数组的时候,比如array[index]=$(NF-1), 则加一句arr=length(arr)?$(NF-1):arr" "$(NF-1)
  4. 最后打印arr,就是array数组的全部值
复制代码

作者: 惟吾无为    时间: 2011-06-23 08:40
awk '{substr($0,start_position,charlength)}'

无此字符类:ascii, 这是bash自己的. posix没有. 怎么办?
作者: 惟吾无为    时间: 2011-06-23 09:39
char~/[[:print:]]/
char~/[[:cntrl:]]/
char~/^$/
else ...
解决了. 就是判断多了点.
作者: 惟吾无为    时间: 2011-06-23 09:45
最后一个问题.
awk 把 ll 结果的前N(可自定义)个域分隔符(至少有一个空格\x20)替换成vfs变量的值.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2