Display all fields except the last

試著忘記壹切 提交于 2019-12-30 17:27:10

问题


I have a file as show below

1.2.3.4.ask
sanma.nam.sam
c.d.b.test

I want to remove the last field from each line, the delimiter is . and the number of fields are not constant.

Can anybody help me with an awk or sed to find out the solution. I can't use perl here.


回答1:


Both these sed and awk solutions work independent of the number of fields.

Using sed:

$ sed -r 's/(.*)\..*/\1/' file
1.2.3.4
sanma.nam
c.d.b

Note: -r is the flag for extended regexp, it could be -E so check with man sed. If your version of sed doesn't have a flag for this then just escape the brackets:

sed 's/\(.*\)\..*/\1/' file
1.2.3.4
sanma.nam
c.d.b

The sed solution is doing a greedy match up to the last . and capturing everything before it, it replaces the whole line with only the matched part (n-1 fields). Use the -i option if you want the changes to be stored back to the files.

Using awk:

$ awk 'BEGIN{FS=OFS="."}{NF--; print}' file
1.2.3.4
sanma.nam
c.d.b

The awk solution just simply prints n-1 fields, to store the changes back to the file use redirection:

$ awk 'BEGIN{FS=OFS="."}{NF--; print}' file > tmp && mv tmp file



回答2:


Reverse, cut, reverse back.

rev file | cut -d. -f2- | rev >newfile

Or, replace from last dot to end with nothing:

sed 's/\.[^.]*$//' file >newfile

The regex [^.] matches one character which is not dot (or newline). You need to exclude the dot because the repetition operator * is "greedy"; it will select the leftmost, longest possible match.




回答3:


If you want to keep the "." use below:

awk '{gsub(/[^\.]*$/,"");print}' your_file



回答4:


With cut on the reversed string

cat youFile | rev |cut -d "." -f 2- | rev


来源:https://stackoverflow.com/questions/13857836/display-all-fields-except-the-last

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!