Tôi đang cố gắng xóa hai cột đầu tiên (mà tôi không quan tâm đến) khỏi tệp nhật ký DbgView. Tôi dường như không thể tìm thấy một ví dụ nào in từ cột 3 trở đi cho đến cuối dòng. Lưu ý rằng mỗi dòng có số cột thay đổi.
Tôi đang cố gắng xóa hai cột đầu tiên (mà tôi không quan tâm đến) khỏi tệp nhật ký DbgView. Tôi dường như không thể tìm thấy một ví dụ nào in từ cột 3 trở đi cho đến cuối dòng. Lưu ý rằng mỗi dòng có số cột thay đổi.
Câu trả lời:
... hoặc một giải pháp đơn giản hơn: cut -f 3- INPUTFILE
chỉ cần thêm đúng dấu phân cách (-d) và bạn sẽ có được hiệu quả tương tự.
awk '{for(i=3;i<=NF;++i)print $i}'
awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}'
( printf
sẽ không in newline char trong khi print ""
sẽ thêm xuống dòng sau khi các trường khác đã được in)
echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}'
, mang đến cho: 3 4 5 6 7 8 9 10
.
awk '{ print substr($0, index($0,$3)) }'
giải pháp được tìm thấy tại đây:
http://www.linuxquestions.org/questions/linux-newbie-8/awk-print-field-to-end-and-character-count-179078/
Câu trả lời của Jonathan Feinberg in mỗi trường trên một dòng riêng biệt. Bạn có thể sử dụng printf
để xây dựng lại bản ghi cho kết quả đầu ra trên cùng một dòng, nhưng bạn cũng có thể chỉ cần di chuyển các trường một bước sang trái.
awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile
NF
POSIX không cho phép giảm bớt.
NF
có thể được giảm bớt.
awk '{$1=$2=$3=""}1' file
NB: phương thức này sẽ để lại "khoảng trống" trong 1,2,3 trường nhưng không phải là vấn đề nếu bạn chỉ muốn xem đầu ra.
1
có nghĩa là gì? tôi nên tìm kiếm với từ khóa awk
nào?
{$1=$2=$3="";$0=$0;$1=$1}1
Nếu bạn muốn in các cột sau cột thứ 3, chẳng hạn trong cùng một dòng, bạn có thể sử dụng:
awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}'
Ví dụ:
Mar 09:39 20180301_123131.jpg
Mar 13:28 20180301_124304.jpg
Mar 13:35 20180301_124358.jpg
Feb 09:45 Cisco_WebEx_Add-On.dmg
Feb 12:49 Docker.dmg
Feb 09:04 Grammarly.dmg
Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf
Nó sẽ in:
20180301_123131.jpg
20180301_124304.jpg
20180301_124358.jpg
Cisco_WebEx_Add-On.dmg
Docker.dmg
Grammarly.dmg
Payslip 10459 %2828-02-2018%29.pdf
Như chúng ta có thể thấy, phiếu lương dù có khoảng trắng vẫn hiển thị ở dòng chính xác.
Còn về dòng sau:
awk '{$ 1 = $ 2 = $ 3 = ""; in lại file này
Dựa trên gợi ý @ ghostdog74. Của tôi sẽ hoạt động tốt hơn khi bạn lọc các dòng, tức là:
awk '/ ^ exim4-config / {$ 1 = ""; in lại file này
sed 's/\s\+//g'
vào cuối lệnh để cắt bớt khoảng trắng ở đầu
awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
Thao tác này cắt những gì đứng trước trường đã cho nr., N và in tất cả phần còn lại của dòng, bao gồm trường nr.N và duy trì khoảng cách ban đầu (nó không định dạng lại). Nó không có giá trị nếu chuỗi của trường cũng xuất hiện ở một nơi khác trong dòng, đó là vấn đề với câu trả lời của daisaa.
Xác định một chức năng:
fromField () {
awk -v m="\x0a" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}
Và sử dụng nó như thế này:
$ echo " bat bi iru lau bost " | fromField 3
iru lau bost
$ echo " bat bi iru lau bost " | fromField 2
bi iru lau bost
Đầu ra duy trì mọi thứ, bao gồm cả dấu cách ở cuối
Hoạt động tốt đối với các tệp trong đó '/ n' là dấu phân tách bản ghi, do đó bạn không có ký tự dòng mới đó bên trong các dòng. Nếu bạn muốn sử dụng nó với các dấu phân tách bản ghi khác, hãy sử dụng:
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
ví dụ. Hoạt động tốt với hầu hết tất cả các tệp miễn là chúng không sử dụng char nr thập lục phân. 1 bên trong các dòng.
Lệnh awk sau đây in N trường cuối cùng của mỗi dòng và ở cuối dòng in ra một ký tự dòng mới:
awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Tìm bên dưới một ví dụ liệt kê nội dung của thư mục / usr / bin, sau đó giữ 3 dòng cuối cùng rồi in 4 cột cuối cùng của mỗi dòng bằng awk:
$ ls -ltr /usr/bin/ | tail -3
-rwxr-xr-x 1 root root 14736 Jan 14 2014 bcomps
-rwxr-xr-x 1 root root 10480 Jan 14 2014 acyclic
-rwxr-xr-x 1 root root 35868448 May 22 2014 skype
$ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Jan 14 2014 bcomps
Jan 14 2014 acyclic
May 22 2014 skype
Chà, bạn có thể dễ dàng đạt được hiệu ứng tương tự bằng cách sử dụng biểu thức chính quy. Giả sử dấu phân cách là một khoảng trắng, nó sẽ giống như sau:
awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'
awk '{ sub(/([^ ]+ +){2}/, ""); print }'
làm mất mẫu đi hai lần.
Giải pháp Perl:
perl -lane 'splice @F,0,2; print join " ",@F' file
Các tùy chọn dòng lệnh này được sử dụng:
-n
lặp xung quanh mọi dòng của tệp đầu vào, không tự động in mọi dòng
-l
xóa các dòng mới trước khi xử lý và thêm lại sau đó
-a
chế độ autosplit - chia dòng đầu vào thành mảng @F. Mặc định chia tách trên khoảng trắng
-e
thực thi mã perl
splice @F,0,2
xóa sạch cột 0 và 1 khỏi mảng @F
join " ",@F
nối các phần tử của mảng @F, sử dụng khoảng trắng ở giữa mỗi phần tử
Nếu tệp đầu vào của bạn được phân tách bằng dấu phẩy, thay vì phân cách bằng dấu cách, hãy sử dụng -F, -lane
Giải pháp Python:
python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file
Trong Bash, bạn có thể sử dụng cú pháp sau với các tham số vị trí:
while read -a cols; do echo ${cols[@]:2}; done < file.txt
Tìm hiểu thêm: Xử lý các tham số vị trí tại Bash Hackers Wiki
Nếu nó chỉ là bỏ qua hai trường đầu tiên và nếu bạn không muốn có khoảng trắng khi che các trường đó (giống như một số câu trả lời ở trên làm):
awk '{gsub($1" "$2" ",""); print;}' file
Trong AWK, các cột được gọi là trường, do đó NF là khóa
tất cả các hàng:
awk -F '<column separator>' '{print $(NF-2)}' <filename>
chỉ hàng đầu tiên:
awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>