Cho đầu vào của mẫu
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar foolkasjfdrte
Làm thế nào tôi có thể cắt chỉ cột thứ hai? Dấu phân cách là TAB và cột thứ hai phải dài tối đa 75 ký tự.
Cho đầu vào của mẫu
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar foolkasjfdrte
Làm thế nào tôi có thể cắt chỉ cột thứ hai? Dấu phân cách là TAB và cột thứ hai phải dài tối đa 75 ký tự.
Câu trả lời:
Nếu bạn chỉ muốn in 75 ký tự đầu tiên của cột thứ hai (bao gồm cả khoảng trắng và giả sử chỉ có hai cột trong tệp), bạn có thể thực hiện:
$ perl -pe 's/(\t.{75}).*/$1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
Hoặc, với GNU sed
:
$ sed 's/\(.*\t.\{75\}\).*/\1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
Hoặc là:
$ sed -r 's/(.*\t.{75}).*/\1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
Ngoài ra, bạn có thể sử dụng fold
, yêu cầu nó cắt ở 91 ký tự đầu tiên (đó là 8 cho mã định danh và 8 ký tự khác cho tab) và chỉ in dòng đầu tiên:
$ fold -w 91 file | head -n1
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
Nếu tệp của bạn có thể có nhiều hơn 2 cột và bạn chỉ muốn cắt bớt cột thứ hai, bạn có thể làm (mà như tôi vừa nhận thấy, chỉ là một cách viết lại câu trả lời của Stephen ):
$ awk -F"\t" -vOFS="\t" '{$2=substr($2,1,75)}1;' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
Hoặc (lưu ý rằng điều này sẽ bị phá vỡ nếu 75 ký tự đầu tiên của cột thứ 2 có thể được hiểu là một biểu thức chính quy):
$ perl -F"\t" -pale 's/$F[1]/substr($F[1],0,75)/e' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
sed
Lệnh đầu tiên của bạn cũng đang sử dụng GNUism ( \t
).
\t
là một chủ nghĩa GNU? Nghiêm túc? Cách di động để mô tả một tab sau đó là gì?
\n
(và một lần nữa không bên trong [...]
có nhiều triển khai), không có trong RHS.
perl
làm cho rất ít ý nghĩa. Hãy suy nghĩ ví dụ về một đầu vào nhưaba\t.*
Sử dụng awk
, phân chia tệp bằng các tab và xuất trường đầu tiên đầy đủ và 75 ký tự đầu tiên (nhiều nhất) của giây:
awk -F "\t" 'BEGIN { OFS=FS }; { print $1, substr($2, 1, 75); }'
Như được chỉ ra bởi fedorqui , bạn có thể xử lý các tệp có nhiều hơn hai trường bằng cách thay thế các trường bạn cần cắt bớt:
awk -F "\t" 'BEGIN { OFS=FS }; { $2=substr($2, 1, 75); print }'
Bạn có thể áp dụng substr
cho nhiều trường bằng cách lặp qua chúng nếu cần thiết.
;
cần thiết thêm ?
/pattern/ {action} {exception-handling}
chẳng hạn). Bây giờ điều đó sẽ cực kỳ khó xảy ra khi bỏ qua những thứ đó ;
là khá phổ biến.
Có thể / POSIXly với sed
:
tab=$(printf '\t')
sed "s/\($tab[^$tab]\{0,75\}\)[^$tab]*/\1/"
Hoặc để cắt bớt mỗi cột:
sed "s/\([^$tab]\{75\}\)[^$tab]*/\1/g"
Nếu chỉ có 2 cột:
sed -r 's/^([^\t]*\t)(.{0,75}).*/\1\2/'
{0,75}
có nghĩa là chọn từ 0 đến 75 ký tự.
.*
là phần bị loại bỏ ngoài char 75.
Nếu có 2 cột trở lên :
sed -r 's/^([^\t]*\t)([^\t]{0,75})[^\t]*(.*)/\1\2\3/' file
[^\t]*
là phần bị loại bỏ ngoài char 75.
sed
và POSIXLY_CORRECT
không có trong môi trường ..
awk 'BEGIN{OFS=FS="\t"} {$2=substr($2,1,75)}1' file